988 words, ~5 min read

Git Patch Stack - Add a Patch

Today we are focused on Git Patch Stack, an open source tool we developed and use for a patch stack based workflow in git, instead of doing feature branches.

What is Git Patch Stack?

You might still be asking, "Well, what is that?" Basically it's a workflow that we can use to conceptually create logically independent patches, and we have a stack of them. So think of a stack of plates. Except, you can do things like reorder them, squash them together, split them apart, etc.

In this workflow you generally work all on the main branch, and it facilitates you building on top of the changes you have already made. Rather than you having to worry about creating a branch that is based on top of another branch and then based on top of another branch and so on and so forth.

It also promotes proper git usage so that you have logical chunks. Enabling tooling like git bisect to actually work.

To learn more about this workflow checkout my post, How we should be using Git.

Adding Patches to your Stack

Today we're going to focus on how we create patches on our stack and what is a stack in terms of git? Git Patch Stack is really just a layer of tooling built directly on top of git itself. So if we look at our git tree here, we have a small project.

Initial git tree with skeleton

It has an initial skeleton of a Rust project. That's just a Hello World program right now, and we can see we have a branch called main that were checked out on. That's why HEAD points to it, and we then have an upstream main with a remote of origin. That happens to be where main points to on our GitHub repository for this.

Technically, in Git Patch Stack terms, any branch that has an upstream is a Patch Stack. So you can have as many of these Patch Stacks as you want, as long as they are branches that have remote upstreams. To add patches on to a stack, you first have to be checked out on a branch that has an associated upstream. In our case, main.

Make a change

Then we just make changes like we normally would in git. We add a commit and that commit conceptually becomes a patch. So let's do that real quick. Let's go look at our source code here. We have a main() function.

fn main() {
    println!("Hello, world!");
}

Let's say that we want to add another function called foo() for some reason, and we want this function to print "Foo", nothing too crazy. So we add a function. We're not even going to use the function. We're just going to add it to the code base so that we can use it in the future.

fn main() {
    println!("Hello, world!");
}

fn foo() {
    println!("Foo");
}

That's it. Now we just do a git diff to verify our changes.

diff --git a/src/main.rs b/src/main.rs
index e7a11a9..0e47771 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,3 +1,7 @@
 fn main() {
     println!("Hello, world!");
 }
+
+fn foo() {
+    println!("Foo");
+}

I have a git alias of di setup so I can just run git di to get the diff quicker. Git Aliases

Once we verify the change is what we want, then we stage that change. We can stage that change by doing a git add of that file. So far, we're just using all normal git commands, and now it's staged. So we can do a git diff --cached and that will show us all the changes that are staged as a diff.

diff --git a/src/main.rs b/src/main.rs
index e7a11a9..0e47771 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,3 +1,7 @@
 fn main() {
     println!("Hello, world!");
 }
+
+fn foo() {
+    println!("Foo");
+}

It looks good. Looks like the changes we want.

I have a git alias of dc setup so I can just run git dc to get the diff quicker. Git Aliases

Add Patch to Stack

If we do a git commit, it pops up my editor and I can enter the commit message

Add foo() function

So that in the future we can print the message when necessary.

Ideally, we provide more context but because this is a contrived example. We don't really have it. Now we have a commit.

Added foo() commit

If we look at our git tree, you can see we have a commit here that we're pointing to on main, which is the "Add foo() function" patch. And then underneath that in the tree, we have the initial skeleton commit we had before.

Now, if we run git ps ls, which is how we list our stack of patches.

We can now see that our stack of patches consist of one commit, the commit that we just added on there, aka a patch.

Add another Patch

So let's add another one real quick just so we can see what it's like to have two. Let's just copy this and paste that, and change this word to bar, change this to bar and then we'll add another function.

fn main() {
    println!("Hello, world!");
}

fn foo() {
    println!("Foo");
}

fn bar() {
    println!("Bar");
}

Now we just git add, git dc to verify our staged code. All looks good. We commit it with the message.

Add bar() function

So that we can print the "Bar" message in the future.

Right now we should have two patches in our stack.

We have patches zero, which is the index of that patch currently. And we have patch index one.

The short sha of those commits, a.k.a. patches visible to the right of the shas. We can also see the patch summaries.

As you get into Git Patch Stack further, you'll see indications here that will indicate things like whether that patch has been requested for review, the patch has been published, or there's been changes since you requested review. But for now that's it.

That's how you add a patch to the top of your stack.

Hope you enjoyed.