After watching your (very enjoyable) talk in the other thread, schacon, one thing struck me - there _is_ a way to work on multiple branches at the same time: worktrees.
What's the advantage of a tool like this over that?
Not sure this is something I need. One thing I do need though, maybe someone knows a solution:
Often I find myself maintaining a handful of "local" changes. I make some changes that only make sense in my local environment, that I don't want to push.
What I end up doing is maintaining these changes as a commit, committing on top of them, and using `git rebase -i` to periodically move them up. Then before I push, I have to temporarily rewind the branch to remove them, push, then cherry-pick them again.
It's all a bit awkward and I would love a tool that maintains a kind of "virtual branch" that isn't shown but is automatically re-based on top every time I make a commit, maybe letting me resolve conflicts or even telling me ahead of time if I've created one, before committing.
Someone must have already solved this, or am I doing it all wrong?
There's a very similar feature which allows you to checkout multiple branches from a single repo, and comes out of the box with git.
Try 'git worktree'
Very cool, congrats Scott!
I have been getting very into jj over the last few weeks, which is larger in scope, but also currently uses git as a backend of sorts and supports similar workflows. Do you have any thoughts/opinions/comparisons to it?
EDIT: I just mentioned this in the jj Discord and schacon is already in there, I didn't realize!
I'm very unclear why this "takes over" the git repository to work. Like even if that was absolutely necessary - and who am I to say it's not - ...surely the "actual" repository can simply live somewhere else and be manipulated?
How do virtual branches differ so completely that managing them isn't just a bunch of behind the scenes checkout/commit commands being issued to another repository somewhere, even if the local worktree needs to be separate?
Particularly because the idea of their being a base branch for virtual branches is pretty much the git branching model. Git and it's tools understand this perfectly fine provided you're using branches, and moving things between branches is supported via cherry-pick.
As usual couldn't recommend stacked git [1] enough. If you prefer CLI it greatly reduces cognitive load about branches/rebases especially if your work with review server allowing to see changes between force pushes (gitlab, gerrit).
Edit: I now realize much (most?) of this already exist as part of the temporarily hidden Timeline feature in GitButler: https://docs.gitbutler.com/features/timeline
Now we just need automatic (possibly virtual[1]]) commits that get created whenever one does a refactoring or other wide, sweeping tool assisted changes and soon my skills as dev archeologist would either become less valuable (because everyone can see what happened[2]) or more valuable (because just like no one I know except me uses bisect no one will use this and it will simplify my job.)
This is (in my opinion) a great idea for a paid IntelliJ/VS Code/etc plug in but I realize I won't have time to do it.
[1]: "virtual commits" is just my marketing speak for adding extra metadata without polluting the branches we usually relate to. One possible way are branches named virtual-<uuid> and IDEs that support them will hide them by default. The plug in commits automatically on the hidden branch while keeping the normal user facing branch at its current commit, and everytime one commits the normal user facing branch the metadata branch is merged as a formality.
[2]: Maybe when I hover over a function I see its refactor history? Maybe I can click on a commit to expand it and see 4 virtual commits:
- edit + successful test,
- refactor + successful test,
- edit + test fail,
- edit + successful test
I started using this yesterday.
I'm a little unsure how to pull multiple real branches into my workspace.
It'd be nice if I could have a virtual branch overlay a real branch so that I could continue working with both the advantage of GitButler and maintain productivity with colleagues that don't use it.
As it stands right now, I'm a bit unclear on how to operate with others who use the old fashioned branching strategy
I really love to tool though. I watched a talk from Scott yesterday, and he has so many good ideas of where to take Git next.
I also LOVE the "CRDT all the changes" idea, and have tried to implement similar solutions using inotify and a "stack of patches" and BTRFs CoW for space saving, with limited success.
> By default, everything in the GitButler client is free to use, but we credit ourselves as the committer in your virtual branch commits. Community members and supporters of GitButler can turn this off.
This is a non-starter, sorry.
It’s hard to get sold on a Git workflow tool that proposes a new (or not supported by git(1)) way of working outside of a long-form article. I see a lot of little paragraphs here and there on the website, like “faq” answers about specific things. But I can’t just piece together “virtual branches” and “doing things at the same time” (or something) and get what this is about. The GitHub blog does as good job of presenting new git(1) features: (1) explains the problem or context, often using several paragraphs and then (2) presents how git(1) can now solve that, concretely.
I would need a concrete case. Maybe how I am working on five different “features” that all depend on each other, maybe serially. And how I can work with a pull request (forge) somewhere and get those merged and at the same time get those virtual branches updated and managed for me. Or at least that’s what I imagine that this is about. Also how existing solutions (there are many of them) fall short or have different tradeoffs.
PS: Including “git butler” in the title... would have been useful.
This seems like an incredibly poor idea to me. You now have the problems of rebase (your commits no longer represent a consistent repo snapshot), but even worse (your commits _never_ represented a consistent repo snapshot!).
Is there a way to identify commits made by GitButler? Can I configure my host to reject them automatically?
And the "generate a commit message for me" button really nails the kind of poor decisions that lead here.
I'm using git-branchless today, with mixed results (have a large-ish monorepo, it's slow when every commit is tagged by CI and restacking broke and only works on a single branch) - I could really use an ascinema recording of a typical two-or-three-branches-in-parallel workflow which need daily rebasing.
Intellij IDE support this through changelists.
UPDATE: add link to documentation https://www.jetbrains.com/help/idea/work-on-several-features...
This looks awesome. I've used git for over a decade and I always have to look up rebase, reset head, etc commands that I use maybe a few times a month.
> Undo, squash and amend your work by just dragging and dropping. No need to wrestle with rebase -i.
I think one thing that would be really cool to add to this and other git actions is to put the git commands that will be run based on the users inputs somewhere on the screen so the user doesn't COMPLETELY forget how to use git, and actually may get better at it with the additional help. Some may think that would lead people to not using gitbutler anymore, but no way, I am absolutely happy never having to write another git command beyond commit and push. Every time I have to do something I don't usually do in git it slows me down by 5+ minutes and it's super annoying and god forbid its a too-big PR that I have to cherry pick etc.
Also, another thing I am DYING for, none of my IDEs (intellij/vscode) as far as I know have extensions/options for it - if I do a commit and push in a vscode session, COLOR THE FILES SO I STILL KNOW WHAT I EDITED. DON'T UNMARK THEM AS EDITED. Make them yellow or blue or something, I don't care, just color them. You can absolutely track git diff / cache etc against 1 or 2 previous merges and base file colors on it. I do this all over my CI/CD scripts to determine whether or not we need to do a docker build/deploy etc or not based on files that diff from origin/main + your current branch 1 behind. If you didn't modify a Dockerfile, we don't do a docker buildx with your push.
I HATE when I have to commit/stash a massive PR with 30+ files edited because I need someone else to pull it or whatever and then have NO easy way to see what I changed in the commit vs main in my UI because as soon as I commit and push all of the tracked files change color to the "im just a file" grey color.
It causes me to commit a lot less when I should commit more. I'm pretty sure at some point I'll have to dive into js and write this myself. Probably just store modified files in a list and diff against main. I have an extension (wakatime) that tracks how long I've written code (not idle time at all, actual typing) in a BRANCH so you can definitely track a session based on something like your time writing code in a branch and cross reference that vs modified files.
The current branch I'm in I've written 4 hours of code in over 1-2 weeks, so I just need to know in that 4 hours what files I touched.
An aside but this is giving me ClearCase config_spec vibes.
Memory is hazy - possibly due to trauma - but you could create a config_spec which would make your view (roughly: working tree) pick up different bits of the filesystem from different branches. Branches might only exist on some of the filesystem, depending on how you set up auto branching and what you checked out, and you had to know what the config_spec rules everyone was working to were or the whole repository was effectively broken.
It was very complicated to get your head around - I guess not helped by the codebase I was working on at the time which tended to concentrate change in the same 20 files.
I have to say- I'm just deadly scared to do this
I'm already quite confused when something wrong happens and I get confusing git messages. To add some more abstractions on top of that... just so scary.
I found the virtual branches compelling, but when I tried it out, I got myself into a mess.
I think that this could all be done using real branches, plus an integration branch with post-commit hooks to backport each commit onto the "default" branch and recreate the octopus merge "integration" commit each time. Would that work, or am I missing something?
Looks like a gimmick to me. You can achieve this easily by working on a scratch branch, and then, once ready (and with git commit -p), building the commits you want. Then, you cherry-pick them into other branches.
The rest of it is pure gimmick and would be force turned off in my team.
It's really confusing to have a windows logo underneath the download link, but then no download for windows.
I guess that windows icon is supposed to be grayed out, but all 3 icons are shades of gray so it's not obvious at all until you mouse over it and see "coming soon".
I think "non-conflicting" is the crux here. I understand this is at the minimal viable product stage, but there are a number of ways to handle that already. To me it only starts to get interesting when conflicts are involved.
The little demo videos embedded on the home page are really sharp! How were they made?
doesn't work with other tools + GUI only => non starter
Slightly offtopic, but because this was prominently featured in their demo:
AI generated commit messages are horrible. I'm not opposed to them in principle, but currently every implementation I have seen uses the code change itself as the context to generate the message. This is just wrong. Commit messages are there to convey information that's explicitly not contained in the code itself and shouldn't just repeat or summarize the code changes (that's what the diff is for). They should contain the reason why the code change was made in the first place, approaches that were considered and did not make it into the code change, etc. Short everything that's not contained in the diff.
AI commit message generators incentivize people to write the wrong type of commit message.
On the positive side, I really like that someone else out there understands that git is mostly simple to understand, so long as you can see all of the concepts laid out for you, and that no kind of node-line timeline or branching tree structure is ever going to be a replacement for a graphical layout of all of the git features. For some time, I thought I was going insane because every time I said "working with git sucks; I wish someone would make a decent GUI", people would insist that 'actually, you should try [x,y,z]; they're really good", only to find out that it's the same command-line-headed nonsense that every other git client thinks is UI. The only thing that saved me is when I started to explain to people what I mean, they would go "oh...yeah...I guess that would help? If you didn't know git? Whatever. Seems like a lot of work for nothing."
And...yeah. That's always been my impression of it. That if you know git well enough to build an app that makes it simple for new users, you might not understand why a new user would need it 'simplified' in the first place. So far, I've chalked it up to that being a frustrating but unavoidable outcome.
So all of that is to say, I'm glad someone built something that treats branches like a "thing" I can "mess with", instead of a timeline that I can indirectly affect through various incantations. And seems to understand the utility of (if not the necessity for) obfuscating a lot of 'stash->checkout->unstash'-type silliness, and all of the branch acrobatics you have to go through to do something as simple as "uncommit a change", or "move this commit's changes over to this other branch". This seems, to me, like a very good idea.
On the other hand, what I'm not particularly thrilled about is the apparent ownership this app takes? Not having interoperability with standard git is a non-starter for me. I'm not going to deal with anyone's proprietary "virtual" anything; there's not nearly enough utility that can be supplied in a VCS that would make lock-in seem valuable to me.
And of course, everything that flows from this mindset is just as tainted. If I have to use your app to create the branch that can be visually controlled, then I won't use your app. It has to work with repos I'm already using. If I have to learn additional configuration or introduce any non-standard areas into my codebase that will cause interactions with other packaging systems to break, that's a no-go.
Git is good. Git works. Don't try to be "better than" git. At least not right out of the gate. Figure out how to make an over-the-top git UI and you've got yourself a customer. But I can't figure how anyone could make an 'embedded' git UI (that changes the way I use version control) that would be useful to me, in any way.
Oh this is very very cool! Way better than dealing with change lists on IntelliJ.
'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,=.