<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Scott Johnson</title>
    <description>The latest articles on DEV Community by Scott Johnson (@jwir3).</description>
    <link>https://dev.to/jwir3</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F242103%2F4850ca8d-4100-48e5-85b4-ffcad5320955.jpeg</url>
      <title>DEV Community: Scott Johnson</title>
      <link>https://dev.to/jwir3</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jwir3"/>
    <language>en</language>
    <item>
      <title>How I Write a Commit Message</title>
      <dc:creator>Scott Johnson</dc:creator>
      <pubDate>Wed, 26 Jun 2019 16:01:27 +0000</pubDate>
      <link>https://dev.to/jwir3/how-i-write-a-commit-message-18l2</link>
      <guid>https://dev.to/jwir3/how-i-write-a-commit-message-18l2</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.jwir3.com%2Fcontent%2Fimages%2F2019%2F06%2FScreen-Shot-2019-06-26-at-10.58.08-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.jwir3.com%2Fcontent%2Fimages%2F2019%2F06%2FScreen-Shot-2019-06-26-at-10.58.08-AM.png" alt="How I Write a Commit Message"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a topic that has been covered at length in other blog posts (most notably &lt;a href="https://chris.beams.io/posts/git-commit/" rel="noopener noreferrer"&gt;Chris Beams' blog post&lt;/a&gt;), but it's important, so it bears repeating. When you're working on a large software project, it makes everyone's life (including yours) much easier if you write consistent, descriptive, and easily readable commit messages.&lt;/p&gt;

&lt;p&gt;Software engineering is tough. You spend all day (or multiple days) getting your feature/bug fix mapped out, writing the code, debugging said code, writing tests to verify that nothing is broken in the future, and then, after all of that, you have to craft your commit(s). It's very tempting to let your discipline lapse and just write something half-baked without thinking too much about it, just so you can get that task into the "Done" state.&lt;/p&gt;

&lt;p&gt;Here's the kicker, though: someday, you're likely going to have to go back and review that commit message. If, for no other reason, you may want to go through your git repository to see what you've accomplished since your last performance review. Going through a git commit log like this (Yeah, this is a real snippet from a commit log that I wrote. The worst part is that those commit messages are &lt;em&gt;all there is&lt;/em&gt;. There's no additional description in any of them):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;85dd75c refactor interfaces so they are all in the same format
2af1c6d add code for branching model
d3b2606 Merge branch 'glsl'
3a6bed2 add necessary graphics libraries
d028509 fix issue #17261
2367d80 more work toward full implementation
2067b23 add cpp files
a111bff makefile generation
14a715e create repo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Is much more work than going through a commit log like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;61c70bc Add a configuration to ripsaw.
8af4151 Merge pull request #7 from jwir3/jwir3/#3-cut-list
9d05854 Add a CutList data structure.
74a21ae Merge pull request #5 from jwir3/main-ui
4be2728 Add a basic user interface for binary program.
de4061d Refactor measurements functionality into its own rust file.
15cc8e1 Merge pull request #1 from jwir3/basics
a6c6010 Add the ability to create nominal and actual lumber sizes.
6a1e1fd Initial commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I can tell &lt;em&gt;exactly&lt;/em&gt; what was changed in each of the commit messages from the latter example.&lt;/p&gt;

&lt;p&gt;Moreover, this is &lt;em&gt;your work&lt;/em&gt;. You've put in the hours necessary to make this code work. The git commit message is your advertisement of the work you've accomplished. It's the thing most of your colleagues are going to see that has your name attached, since, as we're working in code from day-to-day, we typically see the code, not the person who wrote it. Take pride in your work - this is your opportunity to "sell" it to your colleagues!&lt;/p&gt;

&lt;h1&gt;
  
  
  The Rules
&lt;/h1&gt;

&lt;p&gt;There are three basic rules I follow (with an additional, optional one at the very beginning):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;(Optional) Choose a gitmoji to represent your commit&lt;/li&gt;
&lt;li&gt;Add a simple subject in the imperative mood, starting with a capital letter, no more than 80 characters in length, and separated from the body by a blank line.&lt;/li&gt;
&lt;li&gt;Write a body message describing &lt;em&gt;what&lt;/em&gt; was accomplished in the commit, as well as &lt;em&gt;why it was necessary&lt;/em&gt;, wrapped at 80 characters in length, separated from the metadata with a blank line.&lt;/li&gt;
&lt;li&gt;Add all metadata (e.g. ticket numbers, CI commands, etc...) at the end of the commit message.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Choose a gitmoji to represent your commit
&lt;/h2&gt;

&lt;p&gt;I've found that reading commit logs (especially one-line logs) can be made much simpler with an emoji that describes the category of change that the commit falls under. I personally use &lt;a href="https://gitmoji.carloscuesta.me/" rel="noopener noreferrer"&gt;gitmoji&lt;/a&gt;, an informal standard for which types of commits use which emoji, but you can really use anything you want, as long as you're consistent.&lt;/p&gt;

&lt;p&gt;By adding something like 🐛 before your commit, it's pretty clear every time you read it that this commit fixed a bug. I find it helps with parsing, but you have to be willing to &lt;a href="https://github.com/carloscuesta/gitmoji-cli" rel="noopener noreferrer"&gt;add some helper packages&lt;/a&gt; so that &lt;code&gt;git log&lt;/code&gt; works on the command line.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add a simple subject
&lt;/h2&gt;

&lt;p&gt;In the manpage for &lt;code&gt;git-commit&lt;/code&gt;, the following argument is made:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;DISCUSSION&lt;br&gt;
Though not required, it's a good idea to begin the commit message with a single short (less than 50 character) line summarizing the change, followed by a blank line and then a more thorough description. The text up to the first blank line in a commit message is treated as the commit title, and that title is used throughout Git. For example, git-format-patch(1) turns a commit into email, and it uses the title on the Subject line and the rest of the commit in the body.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I've personally found that 50 characters is a little short, although, I can see the point if you're reviewing patches via email. Github seems to truncate the subject line of a commit at 72 characters, so that's worth keeping in mind, too. I set my vim editor (which is what I use to write commit messages) to show a vertical line and automatically add a newline at 80 characters. It's somewhat of an arbitrary limit, but I don't think that 50 or 72 characters is quite enough, personally, and 80 character line limits seem to be a standard.&lt;/p&gt;

&lt;p&gt;I think the idea behind the 50 character limit is that when in a terminal with an 80 character line length limit, the sha of the commit and it's trailing space require 10 characters on average, but they &lt;em&gt;can&lt;/em&gt; require up to 41 characters (40 for the sha itself, plus 1 for the space), thus you really only have 80 - 41 = 39 characters of actual message length. I think, though, that most terminals aren't limited to 80 characters anymore, so this is somewhat moot. Instead, it's a discipline thing: you should be disciplined enough as an engineer to be able to summarize your changes in 50 characters or less.&lt;/p&gt;

&lt;p&gt;That said, here's my argument against limiting yourself to 50 characters: first off, we live in a society that is becoming more and more conditioned to brief communications (think news headlines and tweets). In most cases, the ideal spot for a news headline is 60-100 characters [^2]. 80 characters is a good middle ground in that range for people to be able to digest.&lt;/p&gt;

&lt;p&gt;A commit subject should be in the &lt;em&gt;imperative mood&lt;/em&gt;. What this essentially means is that it should complete the sentence " &lt;strong&gt;When this commit is applied, it will ___________________&lt;/strong&gt;. Think about how easy to read this is when it's properly written in this manner. It also helps you, as an engineer crafting the commit, to know if you've overstepped the bounds of a commit changing a single related and cohesive thing, rather than changing a bunch of things that are unrelated.&lt;/p&gt;

&lt;p&gt;One other detail about the subject that might be controversial: I actually add a period to the end of my commit messages. The reason I do this is because, in my opinion, the subject line of the commit should be a complete sentence. I find messages easier to read and parse when proper punctuation is used, but this is just me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Write a body message
&lt;/h2&gt;

&lt;p&gt;It's important to add descriptive data as to &lt;em&gt;what&lt;/em&gt;, specifically, was changed in your commit (beyond the limit of your subject line). I've found, though, that more important is the &lt;em&gt;justification&lt;/em&gt; for this change. In six months, you might come back to this commit, realize that you changed a file or a class, but you might not remember &lt;em&gt;why&lt;/em&gt; that change was necessary. The body also gives you room to express yourself using lists, bullets, links, or, in some cases (depending on your organization's policies) full markdown.&lt;/p&gt;

&lt;p&gt;It is worth noting that not &lt;em&gt;every&lt;/em&gt; commit requires a subject line and a body. Sometimes, if the subject line is absolutely clear, it's worth just leaving the body blank. I also do this if it's a merge commit, but I will sometimes add the metadata section to indicate who reviewed my merge:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;commit a2f525f01bf657b706fd2f39bbf704aa7b9c4a69
Merge: d9f74c1fd 4530a7243
Author: Scott Johnson &amp;lt;jaywir3@gmail.com&amp;gt;
Date: Mon May 13 16:22:45 2019 -0500

    Merge pull request #5616 from jwir3/bump-versions-package-may19

    [r=VerteDinde, coreh]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Add all metadata at the end of the commit message
&lt;/h2&gt;

&lt;p&gt;We all have things that we need to add to a commit - ticket numbers, references to other commits, who reviewed a given commit, etc... This metadata should be placed at the &lt;em&gt;end&lt;/em&gt; of the commit message. The rationale for this is that this tends to be things that are either required by a continuous integration system (e.g. it should be machine-readable, rather than human-readable), or is ancillary information not directly related to the commit in question (i.e. if your commit is readable enough, why bother going to the original ticket for more information? You should be able to find the answer to your question within the git log itself).&lt;/p&gt;

&lt;p&gt;Thus, I tend to organize my data in a commit in a linear fashion, with the information I'm most likely to want coming first, in this order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What category this commit fits into&lt;/li&gt;
&lt;li&gt;What this commit changes&lt;/li&gt;
&lt;li&gt;A thorough explanation of what was changed and why it was necessary&lt;/li&gt;
&lt;li&gt;Any ancillary metadata that helps me locate more information if this wasn't enough&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  A Config to Help You
&lt;/h1&gt;

&lt;p&gt;I find the following commit template configuration helpful as a reminder of this. Just put the file into &lt;code&gt;~/.gitmessage&lt;/code&gt; and it will show up for you every time you enter the editor after running &lt;code&gt;git commit&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# When applied, this commit will:

# This change is necessary because:

# The following is metadata for this commit:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  How can I get my organization to do this?
&lt;/h1&gt;

&lt;p&gt;There's a small part of this that I've glossed over that makes this all worthwhile. It's only somewhat beneficial if you're the only one in your organization doing this. How can you get engineers from across the organization writing commits like this?&lt;/p&gt;

&lt;p&gt;Part of the answer to this questions is: &lt;em&gt;You can't&lt;/em&gt;. It's not possible to control other people's behavior completely, so you should temper your expectations. People will do things that they believe have value, so if they don't think that writing commit messages in this way has value, they won't do it. There are ways to encourage them to see value in it, though.&lt;/p&gt;

&lt;p&gt;I've found that around 85% of organizations I've been a part of don't have &lt;em&gt;any&lt;/em&gt; documentation on how to write commit messages. If, however, your organization is part of the 15% that &lt;em&gt;does&lt;/em&gt; have a standardized way of writing commit messages, by all means, follow those rules. Otherwise, what I do is to keep in mind a couple of things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The other person isn't you. They have different expectations from their higher-ups (and themselves), so it's not a great idea to try to force upon them a standard that you simply create out of thin air.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Some small things (like the difference between an 80-character subject line and a 50-character subject line) are ideological battles that aren't worth fighting over. If that's the sticking point between you and a colleague, just let them do it however they want, as long as the benefit is still present.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, on to the techniques for encouraging this behavior. I find that &lt;em&gt;core review and micro-rewards&lt;/em&gt; are a great way to encourage the writing of great commit messages. Most organizations have some form of code review process. This is a great place to enforce commit message practices. One thing to be careful about, though, is to not become too dictatorial. If I see a commit message that could be improved during a code review, I will often consider re-writing the commit message for the person in question, and posting that as a suggested change in the code review. Additionally, not everyone knows how to use &lt;code&gt;git rebase&lt;/code&gt; (see also &lt;a href="https://www.jwir3.com/rebasing-toward-independence/" rel="noopener noreferrer"&gt;Rebasing Toward Independence&lt;/a&gt;), so it's worth it to add a comment detailing &lt;em&gt;how&lt;/em&gt; they change their commit message in the code review, as well.&lt;/p&gt;

&lt;p&gt;Keep in mind that you can always &lt;em&gt;suggest&lt;/em&gt; the change be made, but unless the commit message is &lt;em&gt;really&lt;/em&gt; nondescriptive, I typically wouldn't hold up a code review solely on that front. Over time, it will become clear in the log which engineers take the time to write a good commit message and which ones don't. Once other engineers are onboard and have to work with the commit messages another person is creating, peer pressure will eventually win out.&lt;/p&gt;

&lt;p&gt;The other option that I use is &lt;em&gt;micro-rewards&lt;/em&gt;. This is specific to an individual company, but some companies utilize a platform like &lt;a href="https://bonus.ly/" rel="noopener noreferrer"&gt;bonus.ly&lt;/a&gt; to enable employees to reward each other over the course of a month. If I see a commit message that really stands out in a good way, I'll go out of my way to reward that individual publicly so that everyone knows I appreciate that.&lt;/p&gt;

&lt;p&gt;The downside to this, of course, is that your company needs to subscribe to the service in order for you to do this. You can, however, bring good commits up during retrospective meetings, during stand-ups, or even just in Slack on a good day, complimenting someone publicly about their commit messages. Stay away from chastising people who &lt;em&gt;aren't&lt;/em&gt; doing what you want publicly, as that doesn't tend to work well in getting people to change their behavior, and usually makes you look bad.&lt;/p&gt;

&lt;p&gt;In all, you can't &lt;em&gt;force&lt;/em&gt; someone to do what you want them to do, but you can &lt;em&gt;encourage&lt;/em&gt; the path you think is the correct one.&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>writing</category>
    </item>
    <item>
      <title>Rust and Wasm Side-by-Side</title>
      <dc:creator>Scott Johnson</dc:creator>
      <pubDate>Fri, 26 Oct 2018 15:42:57 +0000</pubDate>
      <link>https://dev.to/jwir3/rust-and-wasm-side-by-side-200g</link>
      <guid>https://dev.to/jwir3/rust-and-wasm-side-by-side-200g</guid>
      <description>&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XrP8DB-O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://www.jwir3.com/content/images/2018/10/crab-298346_1280.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XrP8DB-O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://www.jwir3.com/content/images/2018/10/crab-298346_1280.jpg" alt="Rust and Wasm Side-by-Side"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At my work, we're considering using &lt;a href="https://webassembly.org/"&gt;WebAssembly&lt;/a&gt; (hereafter abbreviated as WASM) because it allows us to cross-compile just about any language for use on the web. WebAssembly is a "binary instruction format for a stack-based virtual machine". Basically, this means it's a binary language designed to be run anywhere, but generally speaking, it's used right now within web browsers as a replacement for Javascript modules. One of the languages we are considering using as a source language is &lt;a href="https://doc.rust-lang.org/book/2018-edition/index.html"&gt;Rust&lt;/a&gt;, a new(ish) language designed for type safety, performance, and concurrency.&lt;/p&gt;

&lt;p&gt;As such, I've been reading up the Rust programming language, and, more importantly, how to &lt;a href="https://rustwasm.github.io/book/"&gt;compile Rust to WebAssembly&lt;/a&gt;. After learning from the example module given in the RustWasm book, I decided to convert one of my personal npm libraries from JS -&amp;gt; Rust &lt;sup&gt;[1]&lt;/sup&gt;. The first step in this endeavor was to convert over the existing tests that I had in mocha/chai to Rust's native test format, so that as I added code, I could verify that it was working as I expected it to work &lt;sup&gt;[2]&lt;/sup&gt;. However, the ability to run these tests became an issue when I moved to a WASM target.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;One of the big downsides to compiling Rust to WASM is that there isn't a good way to debug code within the browser, and have it link back to the Rust source. The Rust-WASM book notes this in &lt;a href="https://rustwasm.github.io/book/game-of-life/debugging.html#using-a-debugger"&gt;the section on debugging&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Unfortunately, the debugging story for WebAssembly is still immature. On most Unix systems, DWARF is used to encode the information that a debugger needs to provide source-level inspection of a running program. There is an alternative format that encodes similar information on Windows. Currently, there is no equivalent for WebAssembly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead, they recommend using testing (specifically, automated testing) to identify regressions &lt;em&gt;before&lt;/em&gt; they make it into the build. This is a great idea, and one I obviously support, given my original writing of tests prior to implementing my library. However, there's one big downside to writing tests in Rust when compiling to WASM, as detailed in the &lt;a href="https://rustwasm.github.io/book/game-of-life/debugging.html#avoid-the-need-to-debug-webassembly-in-the-first-place"&gt;next subsection of the Rust-WASM book&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note that in order to run the #[test]s without compiler and linker errors, you will need to comment out the crate-type = "cdylib" bits in wasm-game-of-life/Cargo.toml.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Wait... what? In order to run my Rust tests, I need to &lt;em&gt;make changes to my source repository just to get it to build&lt;/em&gt;? This is a bit of a non-starter for me, because I want to run on a continuous integration system, where I'm able to build the Rust package, run the tests, build the WASM binary, and then deploy to NPM, all &lt;em&gt;automatically&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In other words, what I want to be able to do is something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# These commands compile (and subsequently test) the native Rust code
$ cargo build
$ cargo test

# This command builds the wasm module
$ cargo build --target=wasm32-unknown-unknown
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The key here, though, is that I want to be able to do this &lt;em&gt;without&lt;/em&gt; making any source file or build-file changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Possible Solutions&lt;sup&gt;[3]&lt;/sup&gt;
&lt;/h2&gt;

&lt;p&gt;I spent quite a bit of time trying to determine what I &lt;em&gt;could&lt;/em&gt; do here. One thought that came to mind was that I could have a pre-build script that runs that performs this commenting-out of &lt;code&gt;#[wasm_bindgen]&lt;/code&gt; attributes manually. How this would work is, before building, the script would make copies of everything in the local directory to a sub-directory. It would then switch the &lt;code&gt;crate-type&lt;/code&gt; in &lt;code&gt;subdirectory/Cargo.toml&lt;/code&gt; to &lt;code&gt;lib&lt;/code&gt;, instead of &lt;code&gt;cdylib&lt;/code&gt; and comment out any instances of &lt;code&gt;#[wasm_bindgen]&lt;/code&gt;. Needless to say, I didn't want to go this route - it seemed incredibly fragile and error-prone.&lt;/p&gt;

&lt;p&gt;Next, a coworker of mine suggested I separate the native Rust code from the WASM aspect of the code, and make the WASM library utilize the code from the native library, similar to how &lt;a href="https://www.github.com/fitzgen/geotoy"&gt;geotoy&lt;/a&gt; handles this&lt;sup&gt;[4]&lt;/sup&gt;. This is a great solution, but, when I set up my library, I couldn't for the life of me figure out how to import an enum or struct into the WASM portion of the library.&lt;/p&gt;

&lt;p&gt;Basically, geotoy has a setup where it uses the WASM library to expose a set of &lt;em&gt;functions&lt;/em&gt; that serve as the API for the library. These functions then utilize the data structures in &lt;code&gt;src/lib.rs&lt;/code&gt;. However, the data structures &lt;em&gt;themselves&lt;/em&gt; aren't exposed. With &lt;code&gt;cratchit&lt;/code&gt;, what I want to expose is the &lt;code&gt;Account&lt;/code&gt; and &lt;code&gt;AccountsChart&lt;/code&gt; data structures, as well as the &lt;code&gt;Currency&lt;/code&gt; and &lt;code&gt;AccountType&lt;/code&gt; enumerations &lt;em&gt;directly&lt;/em&gt;, instead of a set of gateway functions that utilize these data structures &lt;sup&gt;[5]&lt;/sup&gt;. I suspect there probably &lt;em&gt;is&lt;/em&gt; a way to get it to expose the structs, but I wasn't able to figure it out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Solution
&lt;/h2&gt;

&lt;p&gt;The solution I eventually arrived at doesn't separate the libraries per se. Instead, it makes the &lt;code&gt;#[wasm_bindgen]&lt;/code&gt; attributes conditional on whether or not you're building for a WASM target.&lt;/p&gt;

&lt;p&gt;The first thing you need to do is make sure you're using &lt;em&gt;both&lt;/em&gt; &lt;code&gt;cdylib&lt;/code&gt; &lt;em&gt;and&lt;/em&gt; &lt;code&gt;rlib&lt;/code&gt; (or &lt;code&gt;lib&lt;/code&gt;) in your &lt;code&gt;Cargo.toml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[lib]
crate-type = ["cdylib", "rlib"]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next, (this might be specific to me), I had to add &lt;code&gt;#![feature(custom_attribute)]&lt;/code&gt; to the top of my crate attributes (i.e. at the top of &lt;code&gt;src/lib.rs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#![feature(custom_attribute)]

extern crate cfg_if;
extern crate json;
extern crate wasm_bindgen;

use wasm_bindgen::prelude::*;
use cfg_if::cfg_if;
use std::collections::HashMap;

...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next, wherever you previously used &lt;code&gt;#[wasm_bindgen]&lt;/code&gt;, make it conditional on the target architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/// Use this instead of #[wasm_bindgen]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen)]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Finally, and this might, again, be something that is specific to my use case, you need to pull types out of submodules and into the root crate &lt;code&gt;src/lib.rs&lt;/code&gt;. In other words, in my &lt;code&gt;src/lib.rs&lt;/code&gt;, I had the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub mod accounts;
pub mod currency;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And I had two files, &lt;code&gt;src/currency.rs&lt;/code&gt; and &lt;code&gt;src/accounts.rs&lt;/code&gt;, which defined types related to accounts and currencies, respectively. &lt;code&gt;wasm_bindgen&lt;/code&gt; didn't appear to like this, so I moved this code into &lt;code&gt;src/lib.rs&lt;/code&gt; and removed references to the modules in the tests.&lt;/p&gt;

&lt;p&gt;What I did to test was not use &lt;code&gt;wasm-pack&lt;/code&gt; initially. Instead, I ran &lt;code&gt;cargo +nightly build --target=wasm32-unknown-unknown&lt;/code&gt; to ensure that no errors were present, and that it created a .wasm file in the appropriate &lt;code&gt;target&lt;/code&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cargo +nightly build --target=wasm32-unknown-unknown
...
$ ls -al target/wasm32-unknown-unknown/debug
total 9520
drwxr-xr-x@ 13 scottj staff 416 Oct 26 10:15 .
drwxr-xr-x 3 scottj staff 96 Oct 26 10:14 ..
-rw-r--r-- 1 scottj staff 0 Oct 26 10:14 .cargo-lock
drwxr-xr-x 8 scottj staff 256 Oct 26 10:14 .fingerprint
drwxr-xr-x 3 scottj staff 96 Oct 26 10:14 build
-rw-r--r-- 1 scottj staff 122 Oct 26 10:15 cratchit.d
-rwxr-xr-x 2 scottj staff 3549051 Oct 26 10:15 cratchit.wasm
drwxr-xr-x 13 scottj staff 416 Oct 26 10:15 deps
drwxr-xr-x 2 scottj staff 64 Oct 26 10:14 examples
drwxr-xr-x 3 scottj staff 96 Oct 26 10:15 incremental
-rw-r--r-- 1 scottj staff 125 Oct 26 10:15 libcratchit.d
-rw-r--r-- 2 scottj staff 1311774 Oct 26 10:15 libcratchit.rlib
drwxr-xr-x 2 scottj staff 64 Oct 26 10:14 native
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And, of course, I made sure the tests ran without any changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cargo test
running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

     Running target/debug/deps/test_accounts-54475044840749bd

running 6 tests
test account_type_from_integer ... ok
test account_creation ... ok
test account_type_from_string ... ok
test adding_top_level_accounts_to_accounts_chart ... ok
test getting_all_account_ids_in_a_chart ... ok
test creating_accounts_chart_from_json ... ok

test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

     Running target/debug/deps/test_currency-d2d59a6d3436c103

running 1 test
test currency_translation_from_string ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

   Doc-tests cratchit

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, when you want to build your WASM module, you can run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wasm-pack build
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And, it will create the packaged WASM library for you in &lt;code&gt;pkg&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus: Run tests on Travis and deploy WASM to NPM
&lt;/h2&gt;

&lt;p&gt;This was another area that took a bit of figuring out for me. The problem I ran into with Travis-CI was that it doesn't install &lt;code&gt;wasm-pack&lt;/code&gt; by default. As such, you need to install it manually in a script. However, if you have &lt;code&gt;cache: cargo&lt;/code&gt; enabled, it will hang if &lt;code&gt;wasm-pack&lt;/code&gt; was previously installed. Thus, I added the following to my &lt;code&gt;.travis.yml&lt;/code&gt; file to conditionally install &lt;code&gt;wasm-pack&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;before_script: |
  if hash wasm-pack 2&amp;gt;/dev/null; then
      echo "Wasm-pack already is installed"
  else
      curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
  fi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, you can add the following to your &lt;code&gt;script&lt;/code&gt; section build both the WASM module and the native Rust module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;script:
- cargo clean
- cargo build
- cargo test
- wasm-pack build --target=nodejs
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note the section that calls &lt;code&gt;wasm-pack build&lt;/code&gt; has an additional argument: &lt;code&gt;--target=nodejs&lt;/code&gt;. If you want to test locally using &lt;code&gt;npm link&lt;/code&gt;, you will need this argument, since it packages the WASM module with a &lt;code&gt;main&lt;/code&gt; parameter in the &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And, finally, add the deployment logic&lt;sup&gt;[6]&lt;/sup&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;before_deploy:
- cd pkg
deploy:
  provider: npm
  email: &amp;lt;your email address&amp;gt;
  on:
    tags: true
  skip_cleanup: true
  api_key:
    secure: &amp;lt;YOUR_API_KEY&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note that this deployment logic will only deploy on tagged releases, so you may want to change that if you want different behavior.&lt;/p&gt;

&lt;p&gt;One last thing to realize: this currently requires &lt;em&gt;nightly&lt;/em&gt; rust. So, you'll need to make sure you're using nightly Rust locally, and you need to make sure that, if you're building on travis, that you allow &lt;code&gt;stable&lt;/code&gt; and &lt;code&gt;beta&lt;/code&gt; Rust to fail:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rust:
- stable
- beta
- nightly
matrix:
  allow_failures:
    - rust: stable
    - rust: beta
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;ol&gt;
&lt;li id="fn1"&gt;
&lt;p&gt;The library in question is &lt;a href="http://www.github.com/jwir3/cratchit"&gt;Cratchit&lt;/a&gt;, which is a library designed to encapsulate accounting data for an accounting application running in electron. It's not important that you have familiarity with this library, but if you want to follow along, feel free. ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn2"&gt;
&lt;p&gt;I'm going to gloss over the rest of the adventures regarding me porting to Rust, since it's not super interesting, and involves me fighting a lot with the borrow checker to get things to work. ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn3"&gt;
&lt;p&gt;If you're not interested in my musings about the problem and &lt;em&gt;how&lt;/em&gt; I came to the solution, feel free to skip to the section on the solution I used, later on in this post. ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn4"&gt;
&lt;p&gt;The coworker in question is &lt;a href="https://github.com/johshoff"&gt;Johannes Hoff&lt;/a&gt; who also is a contributer on the geotoy repo. Interestingly enough, the original author of geotoy, &lt;a href="http://www.github.com/fitzgen"&gt;Nick Fitzgerald&lt;/a&gt;, was an intern at Mozilla when I first started there. It's amazing to me sometimes how small this world is, given that I haven't seen fitzgen in years, and one of my coworkers happens to have a solution to a problem I have, in collaboration with this &lt;em&gt;other&lt;/em&gt; person I worked closely with. Sometimes the wheel of fate astounds me. ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn5"&gt;
&lt;p&gt;There probably is a good reason for exposing gateway functions, rather than the underlying data structures themselves, which I will discover at some future point, but for now, my chosen solution seems to be a little cleaner. ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn6"&gt;
&lt;p&gt;Make sure that you encrypt your api key. You can do this by retrieving an api key from travis-ci.org and then running: &lt;code&gt;travis encrypt &amp;lt;api_key&amp;gt; --add deploy.api_key&lt;/code&gt;. I waited until I had the configuration otherwise the way I wanted it before doing this. ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>webassembly</category>
      <category>rust</category>
      <category>software</category>
      <category>compiling</category>
    </item>
    <item>
      <title>git bisect: A Gentle Introduction</title>
      <dc:creator>Scott Johnson</dc:creator>
      <pubDate>Wed, 31 Jan 2018 01:19:43 +0000</pubDate>
      <link>https://dev.to/jwir3/git-bisect-a-gentle-introduction-1bn1</link>
      <guid>https://dev.to/jwir3/git-bisect-a-gentle-introduction-1bn1</guid>
      <description>&lt;h1&gt;
  
  
  Motivation
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mSRKD0dt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://www.jwir3.com/content/images/2018/01/computer-1833058_1920.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mSRKD0dt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://www.jwir3.com/content/images/2018/01/computer-1833058_1920.png" alt="git bisect: A Gentle Introduction"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagine this situation: You're a software developer who's just been assigned a ticket. It's a bug, and the symptom of the problem is that your app is rendering triangles where it should be rendering quadrilaterals.&lt;/p&gt;

&lt;p&gt;Seems straightforward enough, right? But wait - you are actually given more information. This is a &lt;em&gt;regression&lt;/em&gt;, which means that the app used to correctly render quadrilaterals, and now it's rendering them as triangles. Whenever a software engineer sees a regression, the first thought should be "When was the first time this error exhibited itself?" If you ask the person that filed the bug, you'll probably get an answer like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6LT_te12--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/http://www.jwir3.com/content/images/2018/01/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6LT_te12--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/http://www.jwir3.com/content/images/2018/01/giphy.gif" alt="git bisect: A Gentle Introduction"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why is this question important, anyway? Well, if we can isolate the change where the regression first appeared, we know that the error was in the code that was added or removed when that change was applied.&lt;/p&gt;

&lt;h1&gt;
  
  
  git bisect
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;git bisect&lt;/code&gt; is a tool you can use to run a binary search &lt;sup&gt;[1]&lt;/sup&gt; on a set of commits to (hopefully) determine which one first exhibited the problem. It's a powerful tool, but there's a catch: you have to have a &lt;em&gt;linear&lt;/em&gt; history of &lt;em&gt;independently buildable&lt;/em&gt;, &lt;em&gt;small&lt;/em&gt;, and &lt;em&gt;working&lt;/em&gt; changes in order for it to work in the best manner possible &lt;sup&gt;[2]&lt;/sup&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;git&lt;/code&gt; (which you probably already know or you wouldn't be reading this post) is a tool for controlling revisions of files. You edit files, then &lt;em&gt;commit&lt;/em&gt; them to the repository after validating your changes. &lt;code&gt;git&lt;/code&gt; keeps track of the &lt;em&gt;history&lt;/em&gt; of these &lt;em&gt;commit&lt;/em&gt; objects, effectively building a graph.&lt;/p&gt;

&lt;p&gt;In the ideal case, your commit history looks something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Bwzum3Uj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://www.jwir3.com/content/images/2018/01/Linear-Commit-History-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Bwzum3Uj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://www.jwir3.com/content/images/2018/01/Linear-Commit-History-1.png" alt="git bisect: A Gentle Introduction"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately, through bad commit/merge practices, you can sometimes get into a situation where this history is &lt;em&gt;nonlinear&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hTRHsqJ9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://www.jwir3.com/content/images/2018/01/Crazy-Commit-History.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hTRHsqJ9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://www.jwir3.com/content/images/2018/01/Crazy-Commit-History.png" alt="git bisect: A Gentle Introduction"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fixing a history that is non-linear is beyond the scope of this blog post, but if you're in this situation, you might want to check out &lt;sup&gt;[3]&lt;/sup&gt; for some guidance. &lt;sup&gt;[4]&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;One other important prerequisite is that the regression is &lt;em&gt;reproducible&lt;/em&gt;. If you don't have a regression that's consistently reproducible, you can't test it at each stage. &lt;code&gt;git bisect&lt;/code&gt; relies on the fact that the regression can be tested for at each step in the process.&lt;/p&gt;

&lt;h1&gt;
  
  
  The bisect process
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Basics
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;git bisect&lt;/code&gt; works like this: given an input range of commits, it splits the range in which the regression occurred into two sections using a commit near the center of the range. It checks out this &lt;em&gt;pivot&lt;/em&gt; revision, and based on your input, it determines which of the two ranges on either side of the pivot should be checked next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--f1Q4l66S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://www.jwir3.com/content/images/2018/01/BIsect-Process.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f1Q4l66S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://www.jwir3.com/content/images/2018/01/BIsect-Process.png" alt="git bisect: A Gentle Introduction"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the diagram above, you can see that we have a known "good" commit, a known "bad" commit (usually this is &lt;code&gt;HEAD&lt;/code&gt;, as the regression presumably exists at the current head of the &lt;code&gt;master&lt;/code&gt; branch, otherwise you probably wouldn't need to fix it &lt;sup&gt;[5]&lt;/sup&gt;), and some unknown point where the regression was introduced.&lt;/p&gt;

&lt;p&gt;There are really only four commands you need to know to use &lt;code&gt;git bisect&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git bisect good
git bisect bad
git bisect skip
git bisect reset
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Starting a Bisect
&lt;/h2&gt;

&lt;p&gt;You can start a bisect session with &lt;code&gt;git bisect start&lt;/code&gt; &lt;sup&gt;[6]&lt;/sup&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;scottj|jwir3/master:~/Source/SinkingMoon/website$ git bisect start
scottj|jwir3/master|BISECTING:~/Source/SinkingMoon/website$
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;But, wait... &lt;code&gt;git bisect start&lt;/code&gt; wasn't on the list of commands I said you needed to know. That's because if you run one of the other commands, &lt;code&gt;git&lt;/code&gt; will offer to start the process for you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;scottj|master:~/Source/SinkingMoon/website$ git bisect bad
You need to start by "git bisect start"
Do you want me to do it for you [Y/n]? y
scottj|master|BISECTING:~/Source/SinkingMoon/website$
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Marking a Commit
&lt;/h2&gt;

&lt;p&gt;While bisecting, &lt;code&gt;git&lt;/code&gt; keeps track of the state of each commit. Each commit could be "good" (i.e. the regression is not present in this commit), "bad" (i.e. the regression is present in this commit), or "unknown" (i.e. there isn't enough information to determine whether the regression is present in this commit) To mark the current commit as "good", use &lt;code&gt;git bisect good&lt;/code&gt;. Alternatively, to mark it as "bad", use &lt;code&gt;git bisect bad&lt;/code&gt;. You can also mark a commit that isn't the current commit as "good" or "bad" by adding the commit hash to the end of the command, as in &lt;code&gt;git bisect bad &amp;lt;hash&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once you have marked both a "good" and "bad" commit, &lt;code&gt;git bisect&lt;/code&gt; will check out a commit near the middle of the range and prompt you to test this commit for the presence of the regression:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;scottj|master:~/Source/SinkingMoon/website$ git bisect bad
You need to start by "git bisect start"
Do you want me to do it for you [Y/n]? y
scottj|master|BISECTING:~/Source/SinkingMoon/website$ git bisect good c3a736
Bisecting: 12 revisions left to test after this (roughly 4 steps)
[f2fd95cc92fa63a8a1a38a2ff2a8ccd406286849] Add handling for shapes that were previously considered non-primitive.
scottj|(f2fd95c...)|BISECTING:~/Source/SinkingMoon/website$
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As you can see, &lt;code&gt;git bisect&lt;/code&gt; tells you how many commits are in the range, and about how many manual tests you're going to have to perform to find the regression.&lt;/p&gt;

&lt;p&gt;What you do now is check to see if the regression is in the currently checked-out commit, using whatever process you have available. If the regression &lt;em&gt;is&lt;/em&gt; present in the currently checked-out commit, mark it as "bad" with &lt;code&gt;git bisect bad&lt;/code&gt;. If it's not, then mark it with &lt;code&gt;git bisect good&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There's a special situation that happens when you have a commit that you can't test&lt;sup&gt;[7]&lt;/sup&gt; - you have to skip it using &lt;code&gt;git bisect skip&lt;/code&gt;. You should refrain from overusing &lt;code&gt;git bisect skip&lt;/code&gt;, because if the actual regression happens to fall next to a commit that was skipped, you end up with a range of commits that &lt;em&gt;could&lt;/em&gt; have caused the regression, and &lt;code&gt;git bisect&lt;/code&gt; won't be able to help you any further than that.&lt;/p&gt;

&lt;p&gt;Going back to the output, we see that the next commit to be tested is &lt;code&gt;f2fd95&lt;/code&gt;, but this wasn't on our chart. How can this be the case? The reason this happens is that &lt;code&gt;git bisect&lt;/code&gt; will automatically look through the commits in merged branches:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qWc1cWGa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://www.jwir3.com/content/images/2018/01/Bisect-In-Progress.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qWc1cWGa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://www.jwir3.com/content/images/2018/01/Bisect-In-Progress.png" alt="git bisect: A Gentle Introduction"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you keep repeating this process, eventually you will reach a point where all of the commits are either marked or skipped:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Dgsw-9qd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://www.jwir3.com/content/images/2018/01/Bisect-Complete.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Dgsw-9qd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://www.jwir3.com/content/images/2018/01/Bisect-Complete.png" alt="git bisect: A Gentle Introduction"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git bisect&lt;/code&gt; will report the first commit that contains the regression in a manner like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;commit a73eed9a145bea5c05833f33eb26eec6

Author: Scott Johnson &amp;lt;jaywir3@gmail.com&amp;gt;
Date: Sat May 20 18:44:29 2017 -0500

    Subdivide all polygons into triangles using ear-clipping algorithm.

    Fixes #817.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, you can use &lt;code&gt;git diff a73eed..a73eed^&lt;/code&gt; to see all of the changes in the commit and (hopefully) determine the source of the regression! &lt;sup&gt;[8]&lt;/sup&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Resetting a Bad Bisect
&lt;/h2&gt;

&lt;p&gt;From time to time, you get into a situation where the bisect didn't work properly, or you screwed up along the way without realizing it. If this happens, use &lt;code&gt;git bisect reset&lt;/code&gt;. This will terminate the bisect process, and check out the last revision you had checked out before you started &lt;code&gt;git bisect&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you accidentally mark a commit as "bad" when it should have been "good" (or vice versa), it's kind of wonky to get back to the state where you want to be. You can't just check out that commit and then set it to whatever you want (&lt;code&gt;git&lt;/code&gt; will report &lt;code&gt;Commit XXXXXXX is both good and bad&lt;/code&gt;). What you need to do is output the log to a file, change the one you need to change, and then &lt;em&gt;replay&lt;/em&gt; the log back using &lt;code&gt;git bisect&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Suppose we accidentally marked commit &lt;code&gt;6138263837a802d9b32c9a5a5daf668378384108&lt;/code&gt; as &lt;em&gt;bad&lt;/em&gt; when it should have been &lt;em&gt;good&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git bisect log &amp;gt; /tmp/bisect.log
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The log will look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git bisect start
# good: [f2fd95cc92fa63a8a1a38a2ff2a8ccd406286849] Add handling for shapes we previously considered non-primitive.
git bisect good f2fd95cc92fa63a8a1a38a2ff2a8ccd406286849
# good: [3f4b51f80ac276e471809ed6127b0d893df01875] Re-enable texture filling of arbitrary polygons.
git bisect good 3f4b51f80ac276e471809ed6127b0d893df01875
# bad: [0b72a4ac45df7b483b61a1799557ac952b74b398] Add the ability to rotate the camera 35 degrees off of the normal.
git bisect bad 0b72a4ac45df7b483b61a1799557ac952b74b398
# bad: [7aca2e12f0e76b73a408d4d13aad52d7af1f4a84] Merge branch 'jwir3/#961-ear-clipping'
git bisect bad 7aca2e12f0e76b73a408d4d13aad52d7af1f4a84
# bad: [a73eed9a145bea5c05833f33eb26eec6] Subdivide all polygons into triangles using ear-clipping algorithm.
git bisect bad a73eed9a145bea5c05833f33eb26eec6
# bad: [6138263837a802d9b32c9a5a5daf668378384108] Add package for more general matrix math computations.
git bisect bad 6138263837a802d9b32c9a5a5daf668378384108
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Remove these last two lines (or, alternatively, change the last line to &lt;code&gt;git bisect good 6138263837a802d9b32c9a5a5daf668378384108&lt;/code&gt;, save the file, and then run &lt;code&gt;git bisect replay&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;scottj|(6138263...) *|BISECTING:~/Source/SinkingMoon/website$ git bisect reset
Previous HEAD position was 6138263... Add package for more general matrix math computations.
Switched to branch 'master'
scottj|master:~/Source/SinkingMoon/website$ git bisect replay /tmp/bisect.log
We are not bisecting.
Bisecting: a merge base must be tested
[6138263837a802d9b32c9a5a5daf668378384108] Subdivide all polygons into triangles using ear-clipping algorithm.
scottj|(6138263...) *|BISECTING:~/Source/SinkingMoon/website$
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Automating Git Bisect
&lt;/h1&gt;

&lt;p&gt;There is one other feature of &lt;code&gt;git bisect&lt;/code&gt; I find useful from time to time: the ability to automate the testing process, namely &lt;code&gt;git bisect run&lt;/code&gt; &lt;sup&gt;[9]&lt;/sup&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git bisect run /tmp/script.sh [optional arguments to the script]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Of course, you need to write this script, but it is useful if you can automate the testing process. In other words, if the regression is that the source code won't compile, the unit tests don't pass, or some other thing that's easily determinable by a script, you can have this script do the thing in question, and then return with an exit code of &lt;code&gt;0&lt;/code&gt; if the test passed (i.e. no regression was present in this revision) or any number in the range &lt;code&gt;1-127&lt;/code&gt;, excluding &lt;code&gt;125&lt;/code&gt;, if the test failed (i.e. the regression was present in this revision). The special value &lt;code&gt;125&lt;/code&gt; is only returned if the test can't be run (i.e. the equivalent of &lt;code&gt;git bisect skip&lt;/code&gt;).&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;git bisect&lt;/code&gt; is a tool that you can use to track down regressions in your code. Remember:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;git bisect&lt;/code&gt; &lt;em&gt;will&lt;/em&gt; delve into commits made on separate branches and subsequently merged, provided the merge commits aren’t squashed into a single commit.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git bisect&lt;/code&gt; &lt;em&gt;only&lt;/em&gt; works at the commit level, so it’s more effective if you have smaller, bite-sized commits.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git bisect&lt;/code&gt; can be used to find &lt;em&gt;anything&lt;/em&gt; that was introduced in a specific commit - it doesn’t have to be a regression. You can use it to find, for example, the first time a feature was introduced.&lt;/li&gt;
&lt;li&gt;Even though &lt;code&gt;git bisect&lt;/code&gt; &lt;em&gt;can&lt;/em&gt; be used for many things (see aforementioned comment), it’s better to use some other method of tracking/searching (e.g. recording the features in every release using &lt;code&gt;git tag&lt;/code&gt;), if possible, as it’s likely faster than a manual binary search.&lt;/li&gt;
&lt;li&gt;While you can use &lt;code&gt;git bisect skip&lt;/code&gt; to skip a commit that can't be tested, it's better to &lt;em&gt;avoid&lt;/em&gt; this as it can add ambiguity to your results. (As a corollary, try to &lt;em&gt;only&lt;/em&gt; commit things that don’t have general, glaring errors and that compile and run at the most basic level).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can learn more about &lt;code&gt;git bisect&lt;/code&gt; (it has many other cool things, like the ability to change the terms for a bisect session from "good" and "bad" to anything you want - like &lt;em&gt;present&lt;/em&gt; and &lt;em&gt;missing&lt;/em&gt;, for feature determination) from the &lt;a href="https://git-scm.com/docs/git-bisect"&gt;git bisect documentation page&lt;/a&gt;. It's actually very readable documentation, and I highly recommend giving it at least a cursory glance.&lt;/p&gt;

&lt;p&gt;My biggest recommendation in learning how to use &lt;code&gt;git bisect&lt;/code&gt; effectively, though, is to &lt;em&gt;do it&lt;/em&gt;. When you've identified a problem that you think can be solved with &lt;code&gt;git bisect&lt;/code&gt;, try to solve it using that tool! This will teach you much about the tool. If you have any questions, I'm always open to answering them in the comments below, on slack/IRC as &lt;code&gt;jwir3&lt;/code&gt;, or via email at &lt;code&gt;jaywir3@gmail.com&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  References and Notes
&lt;/h1&gt;




&lt;ol&gt;
&lt;li id="fn1"&gt;
&lt;p&gt;A &lt;a href="https://en.wikipedia.org/wiki/Binary_search_algorithm"&gt;Binary Search&lt;/a&gt; is a special type of search which divides the search space in half, checks one half of it, then recurses on one of the two halves, depending on the outcome of the initial check. ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn2"&gt;
&lt;p&gt;See my other post, &lt;a href="https://dev.to/jwir3/rebasing-toward-independence-gfk"&gt;Rebasing Toward Independence&lt;/a&gt; for advice on how to make sure your repository satisfies these rules. ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn3"&gt;
&lt;p&gt;Geelnard, Marcus. (2015). &lt;a href="http://www.bitsnbites.eu/a-tidy-linear-git-history/"&gt;A tidy, linear git history&lt;/a&gt;. Retrieved 30 January 2018 from &lt;a href="http://www.bitsnbites.eu/a-tidy-linear-git-history/"&gt;http://www.bitsnbites.eu/a-tidy-linear-git-history/&lt;/a&gt;. ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn4"&gt;
&lt;p&gt;If you want to look to see if your git history is linear, try using the command &lt;code&gt;git log --graph --oneline --abbrev=6&lt;/code&gt;. This will show you a graph of your git commits, and you can look to see if it's a linear graph (looks like the first image) or a non-linear graph (looks like the second image). ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn5"&gt;
&lt;p&gt;You should, of course, try to minimize the number of steps in the bisect process, so if you know that a commit earlier than &lt;code&gt;HEAD&lt;/code&gt; is bad, use that one instead, as it will save you time in the bisect process. That said, it's a trade-off between this and manually attempting to find a commit closer to the actual regression, because the closer you get to the regression, the more time &lt;code&gt;git bisect&lt;/code&gt; will spend on the other side of the binary search. Thus, about 85%-90% of the time, I just use &lt;code&gt;HEAD&lt;/code&gt; as my "known bad" commit. ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn6"&gt;
&lt;p&gt;I'm using git-prompt with zsh on Mac OSX for all of the following examples, which is why you'll see the steps remaining when I run &lt;code&gt;git rebase&lt;/code&gt;. Your mileage may vary if you're using a different shell or OS. ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn7"&gt;
&lt;p&gt;Often, this happens because of a compile-time error that was added as a non-final commit in a branch prior to merging. This is annoying, because, unless you can fix it trivially and without biasing the binary search (i.e. accidentally fixing the regression or making it worse), you won't be able to do anything with this commit other than skip it. This is part of the reason why each commit should be independently &lt;em&gt;compileable&lt;/em&gt; and &lt;em&gt;runnable&lt;/em&gt; for &lt;em&gt;each&lt;/em&gt; commit, not just for the last commit on a branch (unless you're using &lt;a href="https://github.com/blog/2141-squash-your-commits"&gt;squash merges&lt;/a&gt;). See also note 2, above. ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn8"&gt;
&lt;p&gt;Depending on the length of the diff, you might be able to see the problem immediately. This is more likely if you have &lt;em&gt;small&lt;/em&gt;, &lt;em&gt;independent&lt;/em&gt;, and &lt;em&gt;straightforward&lt;/em&gt; commits. I tend to abide by the phrase "&lt;strong&gt;Commit early and often&lt;/strong&gt;". This is also the reason I don't use &lt;em&gt;squash merges&lt;/em&gt;, since they combine a bunch of small commits into a single, monolithic commit, and you lose all of this incremental work (and the ability to find the regression in this incremental work). ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn9"&gt;
&lt;p&gt;&lt;a href="https://git-scm.com/docs/git-bisect#_bisect_run"&gt;Git Documentation: Bisect Run&lt;/a&gt;. Retrieved 30 Jan 2018 from &lt;a href="https://git-scm.com/docs/git-bisect#_bisect_run"&gt;https://git-scm.com/docs/git-bisect#_bisect_run&lt;/a&gt;. ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>bisect</category>
      <category>software</category>
      <category>git</category>
      <category>regressions</category>
    </item>
    <item>
      <title>Rebasing Toward Independence</title>
      <dc:creator>Scott Johnson</dc:creator>
      <pubDate>Thu, 08 Sep 2016 21:09:12 +0000</pubDate>
      <link>https://dev.to/jwir3/rebasing-toward-independence-gfk</link>
      <guid>https://dev.to/jwir3/rebasing-toward-independence-gfk</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;One of the things I will usually do when reviewing code is to verify that &lt;em&gt;every&lt;/em&gt; commit within a pull request at least &lt;em&gt;compiles&lt;/em&gt;. Since I learned a lot of my craft from developing and reviewing patches, rather than pull requests, this typically was innate in the structure of the code review. Nowadays, though, it's entirely possible that, while a given &lt;em&gt;branch&lt;/em&gt; compiles after being merged into another branch, not every &lt;em&gt;commit&lt;/em&gt; compiles independently.&lt;/p&gt;

&lt;p&gt;You might ask why I'm such a stickler on this. The answer is twofold.&lt;br&gt;&lt;br&gt;
First, I think that commits should be &lt;em&gt;independent&lt;/em&gt; of one another. This helps in a number of ways, but mostly it's about the way I think. I want to separate my changes into pieces that are independent of one another, because then I can better summarize them in my mind. This helps me think through, in detail, what steps are required before beginning a particular task. In turn, I've found this leads to less errors and more thought &lt;em&gt;up front&lt;/em&gt;, before starting code development.&lt;/p&gt;

&lt;p&gt;Second, I use &lt;code&gt;git bisect&lt;/code&gt; &lt;em&gt;very often&lt;/em&gt; when trying to diagnose a bug that's been found. Bisecting revisions to find where a change occurred is more useful when the commits you're bisecting are small, unrelated, and can be independently compiled. This last part is crucial, because if a specific commit can't be built without adding on other commits, it means you're going to have to &lt;code&gt;git bisect --skip&lt;/code&gt; on that commit if it's a pivot point in the bisection search. This increases the likelihood that you're going to end up with multiple commits that could have introduced the bug.&lt;/p&gt;
&lt;h1&gt;
  
  
  Methodology
&lt;/h1&gt;

&lt;p&gt;Now that I've expounded on the rationale for &lt;em&gt;why&lt;/em&gt; you want your commits to be able to be independently compiled, how does one check that this is actually the case? The answer is &lt;code&gt;git rebase&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You're probably thinking "yeah, I don't touch rebase because it changes the git history." That's a good rule of thumb to have for shared branches (e.g. &lt;code&gt;master&lt;/code&gt; or &lt;code&gt;develop&lt;/code&gt;), but for temporary branches&lt;sup&gt;[1]&lt;/sup&gt;, it's perfectly acceptable to change the history in order to make your commits have a better structure before merging them into your main trunk.&lt;/p&gt;
&lt;h2&gt;
  
  
  Rebasing Interactively
&lt;/h2&gt;

&lt;p&gt;Git rebase has an interactive switch, &lt;code&gt;-i&lt;/code&gt;, that allows you to specify which commits you want to operate on, and what you want to do to them. You just need to specify a starting point (usually your current &lt;code&gt;HEAD&lt;/code&gt;) and an ending point:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout feature/my-cool-feature
git rebase -i HEAD~2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will bring up an editor where you can interactively tell git which commit(s) you want to &lt;code&gt;edit&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.jwir3.com%2Fcontent%2Fimages%2F2016%2F09%2FScreen-Shot-2016-09-08-at-3-51-59-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.jwir3.com%2Fcontent%2Fimages%2F2016%2F09%2FScreen-Shot-2016-09-08-at-3-51-59-PM.png" alt="Example of Editor in Interactive Rebase"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order to edit specific commits, simple change the word &lt;code&gt;pick&lt;/code&gt; at the beginning of each line to &lt;code&gt;edit&lt;/code&gt;. Then, save the file and exist the editor. Git will now start stepping through the commits, one by one, until it gets to the end of the set of commits you told it to edit. At each step, you simply have to determine if the code compiles. If it does, then you can run &lt;code&gt;git rebase --continue&lt;/code&gt; to move on to the next commit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Iterating Through Commits
&lt;/h2&gt;

&lt;p&gt;The following is an example of how you can step through a branch with a large number of commits to determine, manually, if each commit compiles.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; : I'm using &lt;a href="https://github.com/git/git/blob/master/contrib/completion/git-prompt.sh" rel="noopener noreferrer"&gt;git-prompt&lt;/a&gt; with zsh on Mac OSX for all of the following examples, which is why you'll see the steps remaining when I run &lt;code&gt;git rebase&lt;/code&gt;. Your mileage may vary if you're using a different shell or OS.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Check out the branch
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout feature/super-cool-feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Determine how many commits this branch has diverged from the trunk&lt;sup&gt;[2]&lt;/sup&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git cherry --abbrev=6 -v &amp;lt;trunk-branch&amp;gt; | wc -l
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Start git rebase
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Use the commits from the above step in place of XX
git rebase -i HEAD~XX

# You will need to use your editor to make
# all the commit messages start with 'edit'
# instead of 'pick'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check each commit
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Run your compile command. If it's successful, run:
git rebase --continue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Repeat until finished&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Automating It
&lt;/h2&gt;

&lt;p&gt;The above example is fine, and, for most small branches, I'll just do it manually. However, once you have more than ~10 commits, it becomes tiresome. Especially if you've just rebased from master, there were no conflicts, and now you just want to check to make sure everything still compiles, even though you're pretty sure it will.&lt;/p&gt;

&lt;p&gt;Here's a small shell script that will enable you to do this automatically:&lt;/p&gt;

&lt;h2&gt;
  
  
  Fixing a Bad Commit
&lt;/h2&gt;

&lt;p&gt;If you encounter a commit that doesn't compile, you can fix the code to make it compile before running &lt;code&gt;git rebase --continue&lt;/code&gt; again. If you're using the above script, it will automatically stop for you if the compilation failed so you can fix it. Once fixed, you can re-run the script to continue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Now that you know how to quickly check to determine if commits on a branch compile independently and b) how to fix commits that don't compile, I hope you'll use this knowledge to make your commits better. You can also check branches when reviewing code to verify that each commit compiles.&lt;/p&gt;

&lt;p&gt;Be diligent about having a hygienic repository! It will save you tons of time in the long run.&lt;/p&gt;




&lt;ol&gt;
&lt;li id="fn1"&gt;
&lt;p&gt;Almost all of my projects use a variation of &lt;a href="http://nvie.com/posts/a-successful-git-branching-model/" rel="noopener noreferrer"&gt;git-flow&lt;/a&gt;. If you've never heard of it, I highly recommend checking it out. ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn2"&gt;
&lt;p&gt;This command makes use of git cherry, a command I have found extremely useful in the past. You can use it to determine which commits are in one branch but not another. For example, if you wanted to find which commits are in branch &lt;em&gt;my-cool-feature&lt;/em&gt; but haven't yet been merged to &lt;em&gt;develop&lt;/em&gt;, you could use: &lt;code&gt;git checkout my-cool-feature &amp;amp;&amp;amp; git cherry --abbrev=6 -v develop&lt;/code&gt; ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>software</category>
      <category>git</category>
      <category>rebase</category>
      <category>commits</category>
    </item>
  </channel>
</rss>
