& see the description of 'the integration commit' for some detail of how they make it work:
https://docs.gitbutler.com/features/virtual-branches/integra...
Basically anything you do with `git` (or another GUI) will get blown away by GitButler; or if you change branch away from it then it will stop working.
> But if you have multiple branches applied, some git commands wont make any sense.
Sure, because of the way it's implemented. But that's just a variation on what I said really - I like the idea, see value in automating some management so that I can see & work on something that's the amalgamation of multiple branches, but I don't want to (have to) go 'all in' on some third-party tool, it needs to work like an extension of vanilla git for me, so everything else can keep working as normal.
It needs to be implemented in 2D so that git CLI can still understand, to put it in the docs' terms.
Basically all your virtual branches also live in refs/gitbutler/[name] and GB won't touch stuff in refs/heads/ because we like the idea of making sure we're not clobbering things you don't expect us to. You can just think of GitButler as a tool for managing refs/gitbutler branches.
All git tooling work totally fine, even generally if you're using something (like commit) that doesn't really make sense in the context of multiple branches.
With that said, the tool is very cautious not to mess with any existing branches. This is the very reason it operates on a separate integration branch. Switching between the "special/integration" branch and any other branch is also not an issue.
Like if you had three branches and you wanted to see how they will work when they're all merged, and you find an issue in one and want to fix it, GB makes this really simple. You just apply them all and then fix something and make sure it's on the right branch and commit there (and push again if you want).
With Git, you would have to actually do either two merges or a three-head merge, see how it goes, undo the merge, switch to the target branch, commit a fix there, re-merge them all to see if that worked, etc. In Git there isn't a _real_ great way to combine trees without modifying history. We make those things a little more orthogonal.
Take my example before, X-->Y-->Z(HEAD) where each of X,Y,Z here are (at least potentially) multi-commit branches, not just commits; based on top of each other.
If I need to fix something in the 'merged' (I said 'amalgamated' previously exactly to avoid that, but we can stick with scarequotes if you like ;)) result, and it belongs say with Y, then I will either:
git fixup <some-commit-between-X-and-Y>
# fixup = my alias for:
"!f(){ target=\"$(test -n \"$1\" && git rev-parse \"$1\" || git fzsha rev-parse)\"; git commit --fixup=\"$target\" ${@:2} && EDITOR=true git rebase -i --autostash --autosquash \"$target^\"; }; f"
# basically commit -m'!fixup <target-commit>', and then rebase target-commit^ to apply it
or if it belongs as a standalone commit on that branch: git commit -m 'whatever'
git rebase -i Y # and move it to the top so the Z stuff follows it
and then in either case: git branch -f Y <new-location>
# if I'm doing this repeatedly, <new-location> is often HEAD~N, for however many N commits on Z.
For this feature at least, it seems like GB could be implemented as automation/abstraction of that workflow, which (clearly) is perfectly penetrable to git.I've been working like this for more than a decade, so even if GB's better & easier it's a tough sell to partially break interoperability; to need to use GB GUI to manage the situation rather than have it as a choice.
For my own sake, allow me to articulate the core value proposition once more. GitButler's virtual branches permit two novel use cases:
- A developer can lazily assign diffs/changes to belong to separate logical branches while maintaining their content within the same working dir. Those logical branches can be converted to plain git trees at any time. The canonical use case here is doing a bugfix while working on an unrelated feature - with the proposed workflow one can separate those contributions into discrete PRs while still having the content of both within the working dir.
- A developer can apply and unapply the content of remote branches to their working directory for the purpose of testing & review. This is distinct from rebasing and merging because it does not introduce merging or rebasing into the branch that the developer was originally working on.
In any case, we will work on communicating and documenting the tool better.
Also, GitButler, as far as I can think of, never causes normal git operations to fail. It doesn't put the project git repo in a state where git can't operate.
A git branching tool that breaks git branch and commit - what a novel concept!
Our goal isn't to replicate all the commands git can do. It's to try to create an interface for writing Git commits/trees that fits a more typical workflow. The UI is pretty different, but the end result is the same. If we can do that _faster_ than you can do on the command line or with another GUI, most developers are pretty pragmatic and will consider it. That is to say, if we do it well.