'Virtual branches' is a nice idea, but I think the 'don't use other tooling' caveat probably makes it a no-go for me.
It's not exactly the same, but since it's how I achieve the same goal currently, I wish it were implemented instead as automatic management of fork-points & rebasing the currently 'active' branch; even if there isn't one you consider 'active' so you want this merge, there still effectively is as soon as you do anything, so it could just choose arbitrarily or create some (possibly temporary) other branch name to show.
Because while I'm a proponent of rebasing, apparently the 'go-to' guy for git on the team, etc. I won't pretend it's trivial to maintain a chain of dependent branches, or not annoying. A couple more aliases than I currently have would probably help, but it'd never be as good as something like OP just clicking to 'rebase all on master', or where x-->Y-->Z(HEAD) 'switch to work on Y but keep Z', etc,=.
> Quick warning. You cannot use both GitButler virtual branches and normal Git branching commands at the same time, you will have to "commit" to one approach or the other.
& see the description of 'the integration commit' for some detail of how they make it work:
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.
This limitation stems from the fact that GB introduces an additional dimension of versioning on top of Git. One way of thinking of what it does with virtual branches is like "multiplexing" multiple branches onto the same working directory. On the way out they get "demuxed" into plain git trees.
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.
Maybe the problem is that the docs aren't selling me anything that I don't currently achieve by (manually) rebasing? So I'm left thinking I'd rather stick with my current workflow (or maybe motivated to alias it up a bit more) than adopt this limitation.
I think you are right that our documentation does not sufficiently communicate what the application does especially in various corner cases.
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.
This convinced me that it's maybe worth trying. Given the number of tools out there and how easy git feels for me right now (pretty easy), that's a highish bar
Well, one thing we can do is "merge" together multiple non-conflicting branches in your working directory without creating (or, I suppose, having to undo) merge artifacts.
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.
Let me first of all be clear that I believe you have good reasons, and reiterate that I think it's great and want the features, I'm just trying to understand why it doesn't/can't work with my current rebasing workflow.
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.
Sorry I didn't realise you worked on GitButler when you asked.
> 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.
Just to clarify, yes, in order to work on multiple simultaneous branches, you need a tool that knows what that means, which git does not really. But you can also very easily run 'git checkout main' and do whatever and then go back to GitButler and restore state. It's pretty good at knowing what mode you're in.
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.
It works fine. The only thing that is a problem is “branch” and “commit”, things that use the index. But that makes sense. If you have setup two virtual branches and then from the cli run “git commit”, which branch do we commit to?
This makes sense, but I have to say I would find it much less concerning if doing "commit" would apply to some well-defined selection. Either something marked in the UI as "default" or "first" or something so that normal git operations wouldn't cause failure. I realize it makes one of the virtuals special, which is unfortunate, but it means normal command line workflows would be _safe_ even if they wouldn't always provide all the options.
Two things. One is there is a commit dialog per virtual branch. You do a commit on a branch. The selection is all the files/hunks you see on that branch, or you can selectively commit parts of those changes (such as a add -i type commit). It's pretty much identical to how Git (or any other Git GUI) handles commit selection, except you can have more than one branch that you're working with, applied, at a time.
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.
That's great news, and I'll play with it some more to see if I misunderstood the docs. If so there may well be no issue here. Thank you for clarifying.
I think many developers don't want to have to jump to another tool. Myself, I've found the VS Code git client "good enough" (even though I have a Git Tower license). Are there plans for extensions for the tools that support them?
Maybe, but I think most developers are fine jumping to another tool if it makes what they do every day easier or faster.
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.
It's not exactly the same, but since it's how I achieve the same goal currently, I wish it were implemented instead as automatic management of fork-points & rebasing the currently 'active' branch; even if there isn't one you consider 'active' so you want this merge, there still effectively is as soon as you do anything, so it could just choose arbitrarily or create some (possibly temporary) other branch name to show.
Because while I'm a proponent of rebasing, apparently the 'go-to' guy for git on the team, etc. I won't pretend it's trivial to maintain a chain of dependent branches, or not annoying. A couple more aliases than I currently have would probably help, but it'd never be as good as something like OP just clicking to 'rebase all on master', or where x-->Y-->Z(HEAD) 'switch to work on Y but keep Z', etc,=.