惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Latest news
Latest news
G
GRAHAM CLULEY
P
Privacy International News Feed
Know Your Adversary
Know Your Adversary
N
Netflix TechBlog - Medium
C
CERT Recently Published Vulnerability Notes
O
OpenAI News
T
Tenable Blog
Attack and Defense Labs
Attack and Defense Labs
S
Schneier on Security
The GitHub Blog
The GitHub Blog
M
MIT News - Artificial intelligence
PCI Perspectives
PCI Perspectives
博客园 - 司徒正美
Microsoft Azure Blog
Microsoft Azure Blog
MyScale Blog
MyScale Blog
Martin Fowler
Martin Fowler
S
Secure Thoughts
博客园 - 三生石上(FineUI控件)
小众软件
小众软件
T
The Exploit Database - CXSecurity.com
U
Unit 42
The Register - Security
The Register - Security
Google DeepMind News
Google DeepMind News
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
WordPress大学
WordPress大学
B
Blog
Project Zero
Project Zero
NISL@THU
NISL@THU
Cloudbric
Cloudbric
TaoSecurity Blog
TaoSecurity Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
MongoDB | Blog
MongoDB | Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Security Archives - TechRepublic
Security Archives - TechRepublic
I
Intezer
L
Lohrmann on Cybersecurity
Webroot Blog
Webroot Blog
P
Proofpoint News Feed
C
Check Point Blog
Schneier on Security
Schneier on Security
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Hugging Face - Blog
Hugging Face - Blog
I
InfoQ
Recent Commits to openclaw:main
Recent Commits to openclaw:main
T
Threatpost
Apple Machine Learning Research
Apple Machine Learning Research
Spread Privacy
Spread Privacy
The Hacker News
The Hacker News

Butler's Log

Agentic Version Control Benchmarks Grit: rewriting Git in Rust with agents Git Merge 2026 Agent-safe Git with GitButler We’ve raised $17M to build what comes after Git Announcing the GitButler CLI for Linux The Great CSS Expansion A couple of git nits Simplifying Git by Using GitButler Introducing the GitButler CLI GitButler 0.19 - "Commander Keen" But Head: Crafting a Custom Font MCP vs RAG: Two Very Different Ways to Gain Context Getting Started With GitButler Agents Using the GitButler MCP Server to Build Better AI-Driven Git Workflows Using GitButler With Multiple GitHub Accounts Advent of Code! Upcoming GitButler Events Use GitButler for your Gerrit workflow Integrating GitButler and GitHub Enterprise Butler Flow: shipping code faster (but less like Alfred, more like CI on steroids) - Part 3 Butler Flow: shipping code faster (but less like Alfred, more like CI on steroids) - Part 2 Butler Flow: shipping code faster (but less like Alfred, more like CI on steroids) - Part 1 Grid Happens: Because Flexbox Wasn’t Enough Using Cursor Hooks for automatic version control Deep Dive into the new Cursor Hooks A Responsive Item Counter with CSS only GitButler 0.16 - "Sweet Sixteen" GitButler's Claude Code tab GitButler's Annual Open Source Pledge Report Git Mini Summit 2025 Videos Automate Your AI Workflows with Claude Code Hooks Managing Multiple Claude Code Sessions Without Worktrees GitButler 0.15 - "Quirky Quinceañera" 20 years of Git. Still weird, still wonderful. GitButler's new patch based Code Review (Beta) Going down the rabbit hole of Git's new bundle-uri How to do patch-based review with git range-diff How Core Git Developers Configure Git Why is Git Autocorrect too fast for Formula One drivers? Stacked Branches with GitButler Git Merge 2024 Talks are Up GitButler 0.13 - "Lucky Baseball" Fearless Rebasing Git Merge 2024 Why GitHub Actually Won GitButler is joining the Open Source Pledge The New Era of Town Hall Chat The Future of Open Source GitButler is now Fair Source Git Merge 2024 GitButler 0.12 - "Stingy Baker" The Birth of THE MERGE GitButler for Windows Fixing up Git with Autosquash The Git Zeitgeist Git Worktrees and GitButler DevWorld Git Slides Git Tips and Tricks Git Tips 1: Oldies but Goodies Git Tips 2: New Stuff in Git Git Tips 3: Really Large Repositories FOSDEM Git Talk Opening Up GitButler Debugging Tauri in VS Code Advent of GitButler Code Signing Commits in Git, Explained Virtual Branches Alpha Our We Are Developers Adventure DevDays in Vilnius The Future of Software and Open Source Introducing GitButler
Building Virtual Branches
Scott Chacon · 2023-07-06 · via Butler's Log

GitButler has come up with an entirely new way to work on multiple branches: simultaneously.

What are virtual branches and how did we come up with them? Here's some behind the scenes gossip about a cool new idea coming soon to the land of Git workflows.

But first, watch the demo:

My alpha product demo for virtual branches. It's an actual background, even though it looks like a green screen.

We're closing in on releasing an alpha build of our new GitButler client with virtual branch functionality. Here's a little behind the scenes of how a startup builds a cool new idea.

First of all, what are virtual branches? Also, why did we name them like this?

Virtual branches are similar to Git branches, except that you can be on several at the same time. So instead of having to determine if you are on a bug fix branch or your feature branch or a coworkers feature branch that you're reviewing, you can actually apply all of them as though they were merged but not have to commit a merge into your history or unroll a test merge.

So why "virtual branches"? Well, we wanted to come up with a name that implies that the branches are lighter weight than Git branches in that you can move between the work on them much easier. We thought of all the following names as well:

  • Stacked branches
  • Union branches
  • Smart branches
  • Integrated branches
  • VIP (virtually integrated proxy) branches

We nearly went with "smart branches" but "virtual" won out in the end. Maybe another blog post on this ridiculous decision making process at a later date.

GitButler is building a next generation version control system that sits within the Git and GitHub world. This means that it's meant to be compatible with Git data transfer protocols, but it can keep data and structures that are not stored in the Git database.

Our first builds were around watching changes to your filesystem and recording every file change so you didn't have to do 'WIP' commits. Once that was working well, we started looking at Git commands we wanted to come up with better tools for. One of the first was branches, since that's what most people use every day.

My first shot at a branches interface was rather similar to how GitHub displays your branches. It had ahead/behind information, authors, last commit date, etc. It was conceived to be a better git branch, but not much more.

Our first working branching screen

In my mind, it was innovative. This isn't how git branch shows you data, but it's more or less the same data that most Git clients have around branching. In my mind, I cared about different information of my branches than most Git clients give you. I hate log graphs, because I've never answered a valuable question with them. I care about ahead/behind data from a target branch, or other branch comparisons.

When Matthias started, he challenged us about this model. What is really innovative about it? Is this really solving the problems that modern developers have in a compelling way? Is it really saving people time or friction?

They are great questions.

This helped us think backwards, rewind what we thought we knew about branching and version control. What do developers really want to do? Branching in Git is great, way better than previous tools, but what biases are clouding our judgement here, what assumptions are we not recognizing as poorly grounded?

What struck me is how often developers stash, pull and pop. How often we commit bug fixes into feature branches because it's a pain to separate them. How much time we actually spend managing our branches so that we can use them.

So I thought, "what if you could be on several branches at the same time"?

It's an interesting question. What actually stops us from doing this?

From a technical Git perspective, it's mostly that we only have one index file. There is only one staging area that can be committed into the next commit on a branch. But what if each entry in that index could be earmarked for a different branch? What if you could commit only the earmarked work that was staged for some of the entries?

To take it a step further, what if each hunk of your changes can be earmarked for a different branch?

So I put together an internal demo. I wrote a proof of concept using the Rugged library in Ruby over the course of a long weekend and presented the concept internally. Here is my internal demo pitch:

Once we had something concrete to talk about and think about, we all decided this would be worthwhile to build out. So for the last few weeks, we've been working hard on figuring out how to build this.

Kiril pitching a Kanban style layout for our virtual branches

First we sketched. We often use Excalidraw for rough concepts, then whiteboard things out to discuss the concepts in more detail, and then once we've figured out the rough direction, our design-master Ian comes up with tons of options for us to discuss in Figma.

We decided that a kanban style board for our branch lanes would make the most sense for splitting out work in progress into multiple virtual branches.

One of my early Excalidraw concepts, for us all to ponder.

The team discussing the different approaches, in fast forward.

A million dreams, by Ian.

Once we had some good ideas about how we wanted this all to work, we got to the coding part.

We started with basic drag and drop issues, trying to see if we could get the UI to work the way we wanted with our Svelte frontend (we're using Tauri for our app). We started with some dummy data that was pulled from our project's pull requests and then implemented a backend that could provide that data structure.

Kiril and Matthias's dragging and dropping working, but no real data yet. Also, light mode.

Once Nikita and I got the data actually reading and writing properly, with all the fun Git (libgit2 via the Rust git2 library) stuff working, we finally had something that is pretty close to useable.

Our internal demo once Nikita and I got the branch application and stashing functionality working.

From my initial internal demo trying to sell the team on the concept on May 23rd, to the functioning external demo that I shot on the 4th of July, our team has been working on this for only about 45 days and we've really excited about how cool it is and how quickly we were able to get it working.

While we're very close to having something to get into people's hands, there are still some relatively common edge cases that we need to work out first. We're hoping to get this to our alpha testers in the next few weeks. Go ahead and sign up for our waiting list if you're interested in being an alpha tester.

We hope you've enjoyed this short journey through the making of a feature. Let us know if you want to know anything else about our startup life. :)