I find people are religious about being git cli purists and only interacting with it in this black box (the terminal). On top of that a lot of people stop learning git after add commit push pull branch and merge so concepts like rebasing and cherry picking are scary.
In this day and age we have state of the art GUI tools that change the game and allow git users to see and interact with the state of a git repository in real time. It's a great way to demystify things like rebasing and interactive rebasing because they show you what's happening in a modern UI designed specifically for git.
I often suggest git CLI purists to get something like git kraken and just use it as a visual dashboard. Watch what happens when you run git commands. You can see everyone else's remote branches and have a much better idea of what's going on than you can without it.
I've worked on teams that just didn't rebase at all and I think people are oblivious to the mess they make on branches with their chaotic merge strategies.
These days, I tend to envision the state of the branch that I want and make that happen. It's so easy to create a new branch before I do anything that if I think something might go south, I just hard reset to my previous state (a branch I created right before the operation)
Gitkraken also has an undo button that handles all sorts of scenarios and I rarely click it without getting exactly what I expected.
> I find people are religious about being git cli purists […] we have state of the art GUI tools
I would humbly suggest you avoid framing it that way, even if you believe it’s true. From someone who is only sometimes a cli advocate, my immediate assumption is that your opinion here may be formed out of naïveté and a bit of fear of the cli.
Please note I’m actually quite a fan of using various GUI tools for basic git workflows, and things like branching diagrams and even diffs are much better in GUI tools than in the console. Some of the tools are damn good and damn convenient most of the time. So you’ll get a huge amount of agreement from me about the benefits of sometimes using GUIs.
But git was designed around the command line, and there are no GUI tools (Kraken included) that have UI for everything or even most of what git can do. Advanced workflows and repo spelunking often require the command line. Using the cli is the only interface that can do everything, and it’s the advanced interface, so telling people who are already advanced (possibly more advanced than you) and already comfortable on the command line that they’ll find enlightenment in GUI tools isn’t always or even generally true. It’s not hard on the command line to see everyone else’s remote branches. Better to listen to them, and suggest GUI tools only when they express frustration about their workflow that you think a GUI can help with. Also perhaps better to ask the about CLI workflows and find out some of the benefits. One benefit is that CLI workflows are always usable over basic ssh connections.
And worth mentioning, the question’s partially moot for people using Github or other hosting services where some GUI tools are built-in. Using the CLI for all interactions with Github, and using the site for the visualizing diffs & branches is totally reasonable.
> I’ve worked on teams that just didn’t rebase at all and I think people are oblivious to the mess they make
I have to fully back you up and agree there! It’s unfortunate that rebase is a little scary and that some people just don’t like it. Rebasing local work before publishing it is the way git was designed to work, and it’s extremely helpful for creating a history that’s not insane. Squash commits are better than nothing I guess, but you can really tell and appreciate when people are comfortable with rebase and care whether their history is presentable.
I'd really like to know what mess people make when they don't rebase.
I've found that using merge gives a readable trail of when something was merged, whether that be from a branch's original branch, or if you're merging into another branch.
Rebasing just seems to cause a lot more headache when something doesn't go perfectly correct in between commits.
Some people are good at making changes relevant only to one task, making commits at appropriate points to that task, and ensuring that none of the intermediate commits are regressions. Sometimes people prefer to deal with future pain of complicating a bisection with broken, unrelated issues.
Personally, I make a lot of mistakes. I commit too early when I missed some bugs or broken builds (eg build on release but not debug, rhel X but not rhel Y). My working area has unrelated changes. I forget to change branches...
So, I figure out what the destination looks like, do my best to keep things clean and small, and rewrite history before the PR as if I was one of those careful people.
My recent advancement has been to realize that reordering commits for an efficient fixup is much easier than splitting commits, so I'm better off doing things out of order. I also use worktrees to be able to ensure each commit is correct as checked out without stale state.
> I'd really like to know what mess people make when they don't rebase.
I think this part is really telling:
> And worth mentioning, the question’s partially moot for people using Github or other hosting services where some GUI tools are built-in. Using the CLI for all interactions with Github, and using the site for the visualizing diffs & branches is totally reasonable.
GitHub's branch view is uniquely awful, and doesn't try to call out branch history at all. Commit lists should either include a railroad diagram or only include the left-facing history. Anything else is just inexcusably broken.
No disagreement from me, so I don’t know what that snippet is telling you. I wasn’t saying GitHub or any other service is the greatest, I was only saying that using the GitHub site mixes GUI and CLI workflows, since using GitHub is so common.
In some sense that goes to the point that CLI can be better than some GUI tools. The ascii railroad diagram you get with git log might be preferable to what GitHub can do.
> Rebasing just seems to cause a lot more headache when something doesn't go perfectly correct in between commits.
You mean merge conflicts? Rebase gives you an opportunity to deal with small merge conflicts arising from single commits. I much prefer that to a big merge commit dealing with all the conflicts simultaneously.
Also, rebase makes the merge conflicts disappear for future readers, making the included commits nicer to read.
Is this about rebasing vs merging or is it about whether to use `git rebase -i` to polish my own commits?
Sometimes I think maybe we should have two different names for these commands.
I think an interactive rebase requires a good mental model of the changes to split or merge them correctly in addition to knowing the CLI. I find it quite hard at times.
Interesting take. If anyone care to actually learn how git works when rebasing, then it becomes much simpler. I always rebase and in 10 years of professional use, never once had a problem with it. That doesn’t mean other people don’t.
> If anyone care to actually learn how git works when rebasing, then it becomes much simpler.
That's a very arbitrarily vague answer. It's very easy to hand-wave the misuse of a tool just by saying "you don't know it well enough". It's much harder to admit that maybe the tool is just difficult to use in the first place.
I have similar experience as the person you are answering to. Unlike them, I got into rebasing only recently. It isn't really a hand-wave of saying 'you don't know it well enough'. This paradox is caused by a quirk in git's design. Git uses a hybrid model for dealing with versions. It uses snapshots for storing them, as well as for operations like fetch, clone, etc. But that mental model causes a lot of confusion for operations like merges, pulls etc. Git uses the diff-patch model for those operations. Even weirder, much of git is actually designed to use the diff-patch model. The first time I ever got a grip on those operations was when I did rebasing. I found git much easier to understand when I could attribute each operation to the model git uses behind the scenes.
> It's much harder to admit that maybe the tool is just difficult to use in the first place.
That is unfortunately true. Git feels like a tool with several parts that were bolted on to solve problems its users (developers) faced. I didn't have that same difficulty with mercurial. I get this feeling that a pure patch based tool like pijul would match their workflow well and still be easy to learn.
Naw, merge is orthogonal to cleaning up local history. Merging a mess is still a mess. Some people are fairly clean from the start, and some aren’t. And it depends on the task at hand, messes are easier to make when you’re doing more than one thing at a time.
Do you care to explain? How can you have a worst history when the `main` / `develop` branch have a linear history? I rather have a linear history where git bisect is trivial to use then a mess of merges and a hard to follow history.
This is my reaction based on experience too. I find that in most companies I've worked at that there are generally 2 camps; one is the "I want history to track what I've actually done; good, bad and ugly", the other is "I don't want to wade through 1000 "typo" commits - they should be pretty and streamlined".
I fall into the former camp, but others (who I respect) fall into the latter.
FWIW, I was mainly referring to making local branches presentable and/or just organizing things, not to rebase as a merge strategy. Don’t assume that rebase always means moving the local branch to the head of main, and don’t assume that rebase and merge are interchangeable. There are a lot of ways to rebase.
That's what I thought the discussion was about, locally 'clean' commits. In this context Rebase is so much more useful. I recently had to use the 'unto' option of the rebase command. 'unto' may show someone that they didn't really understand rebase though they could use the simple form of it, rebase -i x.
I'm someone who has started enjoying rebasing workflow after using branch-merge workflow for more than a decade. So perhaps, my experience may be useful since you can compare the same person using both of them. The first thing to realize is that branch-merge and rebase workflows try to achieve different goals. Branch-merge tries to preserve history of the code, with every wart and quirk included. Rebase tries to achieve a clean history where every commit is an entire fully functional (without known errors) feature with complete explanation in the commit message. People fight over them, but I find both goals to be meaningful and the choice depends on your priorities. In fact, I do both- publish a clean history in the master and the original messy history as a separate branch.
> I'd really like to know what mess people make when they don't rebase.
As a developer, we have the expectation that git will allow us to experiment with features, make mistakes, correct them, roll them back and improve. That stage is also so messy that you'd leave short commit messages that would make sense only to you. This is fine while developing. But this leaves many commits that are functionally broken, partial or rolled back later. That, along with vague commit messages and illogical commit order make it really hard for someone else to pick up a working commit from your branch and continue. Heck! I find it hard to choose a commit even from my own older repositories. That isn't the case with good projects like the kernel. You can pick any commit on the master and it will compile and work with all the features advertised up to that commit message. It makes a users' life easier.
> I've found that using merge gives a readable trail of when something was merged, whether that be from a branch's original branch, or if you're merging into another branch.
This is true. It's harder to achieve with rebasing. But it's possible with some work. I usually leave the original messy feature branch intact, and mark the rebased HEAD with a similar-worded tag or branch.
> Rebasing just seems to cause a lot more headache when something doesn't go perfectly correct in between commits.
Don't take any offense, but those are beginner blues. It happens in the early stage of learning rebases when you don't have a full grasp of what is going on. People evolve different strategies to overcome this once they are a bit more comfortable. My strategy is to create a temporary branch for rebasing (at the same commit as the feature branch) and do multiple rebases on it. I do only one or maximum two operations during each rebase. The result of each rebase is reviewed before doing the next round of rebase on the same branch. The original feature branch is left intact in case something goes wrong - though I never needed it.
Other people do rebasing occasionally while developing the branch. They do this after every two or three commits. They end up with a clean history to merge (fast-forward) to master, by the time they finish the branch. All of these operations can be simplified using helper tools like git-revise [1].
My absolute favourite method is to not use rebase at all. Craft the perfect commits as you develop. This can be achieved with a patch stack tool like quilt or stacked-git [2]. It allows you to move your changes to a patch (commit) of your choice. This is like having multiple staging indexes available. You can also split, combine or reorder patches. The patch stack evolves as you develop, but you end up with a perfect history to merge (fast-forward) at the end.
As a counter point. Every time I've seen people get themselves into trouble with git has been when they are using a GUI tool. I have yet to see a gui tool that they can use to get themselves back out of it. There's a lot of value in knowing your way around the command line side of git even if you regularly use gui tools to interact with the repository.
I have the same theory, and had the same experience: I worked for a company where it was impossible to clean up the repository, because a dev using a GUI was regularly pushing back the old tags (and consequently, references to old history), without knowing they were doing it. It was never discovered who they were, since almost the whole team uses Git via GUI.
I've had the exact opposite experience. I've had to bail out cli purists because they just can't see what went wrong.
Objectively git kraken has more visual information density. To get the same information on the cli requires multiple commands and the user has to hold the information I'm their head between the commands.
Git kraken's buttons are also tightly correlated to commands and you can even bring up a window that shows what cli commands are being run under the hood.
Gitkraken has too much information density, since it weights nearly everything equally or alphabetically. Next to impossible to see what you or your colleagues are working on when there are a lot of branches in flight and half of what Gitkraken is showing you are merged or abandoned branches you don't care about. It also gives up and freezes when opening large repos, like my small company's monorepo.
I canceled my subscription and returned to the CLI + VS Codes native SCM UI because GitKraken is now useless in my work environment. Never mind the startup time is in minutes. And no, I'm not paying more for the ability to write a bug report and get it to them (their support is functionally non existent)
Great for a tiny project. Awful for companies. Not worth the money given how much more time it takes for me to do my work than use the CLI.
Sorry for the strong words, GitKraken is just a great example of bad design.
> Objectively git kraken has more visual information density. To get the same information on the cli requires multiple commands and the user has to hold the information I'm their head between the commands.
Can you give a precise example? The cli has support to using visual tools for diff/merge, so one doesn't need to use git via gui in order to use graphical interfaces where effective.
> I find people are religious about being git cli purists and only interacting with it in this black box (the terminal)
Git cli purists are probably cli purists in general, not just for git. And for good reason.
When you work with the cli/terminal, you aren't bound by what the creator of the GUI decided should be built.
> I often suggest git CLI purists to get something like git kraken and just use it as a visual dashboard. Watch what happens when you run git commands. You can see everyone else's remote branches and have a much better idea of what's going on than you can without it.
There are git commands for displaying whatever information you want, capable of drawing nice trees and whatever complete with everybody else's branches.
> It's so easy to create a new branch before I do anything that if I think something might go south, I just hard reset to my previous state (a branch I created right before the operation)
Duh! That's what git is for!
And when you say "It's so easy to create a new branch" I'm genuinely curious to know how you've been creating branches before you discovered the "state of the art GUI tools that change the game".
Some operations lend themselves well to a graphical interface, such as partial staging and interactive rebasing. Others might not. As long as you show and read before pushing to a remote repository, the worse you can do is create extra work for yourself.
However I'm not sure Kraken is a good example. The GUIs for git are all similar, but Kraken has some unfortunate combination of being counter intuitive at times, and very easy to access undo and force buttons.
We have a lot of developers using all common GUI tools and the ones using Kraken are the only ones who not only regularly end up not only shot in the foot but force pushing the remnants upon their colleagues. For what it's worth, the few using Magit seem to have the least trouble but I suspect they may be more familiar with their tools. The ones using IntelliJ seems alright too, as long as they don't venture too far outside the familiar edit and push cycles.
Generally, any graphical git tool should probably be as closely integrated into the IDE as possible. That's where it's most useful.
> Some operations lend themselves well to a graphical interface, such as partial staging and interactive rebasing
I can't emphasize how pleasant those operations are in magit. I'm not sure if it (TUI) would be considered as textual or graphical. However, the interface model should lend well to a fully graphical implementation.
What GUI tools did you have in mind? git CLI is spectacularly good, GUIs tend to just make things slow and get in your way. With CLI you will also get the same experience on every platform, and even when you SSH.
The reason I learned about cherry picking, rebase & all is because when I tried using IntelliJ's UI to see my history, I saw a lot of options in the context menu and just searched what they meant.
It is also with a GUI that I learned you could rebase on pull, instead if merging and getting an ugly "Merged remote tracking changes" commit.
How many GUI tools support git's bisection search?
Just last week, I found out that GitKraken doesn't support connecting to multiple Azure DevOps organizations within the same profile. So my team now needs to learn git CLI anyway, to efficiently migrate our 30-odd repositories.
Totally agree. Using git with a UI is much more enjoyable, albeit less purist but who cares. I'm working on 4 different features, more important to be efficient than pure.
If you want to use a private repo on GitHub with GitKraken, it will cost you $60 per year per user, minimum. Everyone wants to embrace, extend, and make a buck!
I think the thing that’s at the root of most git issues is the lack of atomic commits. Most people I know commit at the “block of work” or “ticket” level. Once they have the thing they wanted done, they commit. It means that fundamentally they can’t cherry pick, and rebasing occurs on huge blocks of code instead of single lines.
It’s not there yet, but I kind of think git should be used the way I started using the save option when computers were less reliable. Type a sentence, save. Type another sentence, save.
Funny. The way I found to not get yelled at for having too many commits is to just “git commit —amend” every time I want to checkpoint and only push when the ticket is done.
Git has an extraordinary collection of foot guns and unwritten rules. I’ve been using it three years and often feel like I just get by (and also the devs who came up with the conventions in my org maybe could have chosen better)?
For me git is really difficult, and the CLI makes it even more so. That's just my personal experience. That's just me. I have a really terrible short term memory, so when using a CLI I tend to scroll up and down a lot since I forget after a few seconds what was the error I was just shown and what state I'm in. This creates a lot of friction. When using a GUI I see the new state immediately, in a single glance.
My theory is that people who like the CLI have a good (or just working...) short term memory.
I have a sample of 1 to prove my case: my SO, who has excellent memory (short and long term) and handles the git CLI just fine, and really thinks all git guis are like bicycle training wheels for kids.
I on the other hand use tortoise git almost exclusively (and get mocked by her that I'm still riding on training wheels...).
I actually use only Tortoise Git's git log view, all the important actions are available from there, instead of accessing them from their somewhat haphazard right-click menu. In this way it is very much like Git Kraken or SourceTree but more powerful, since it exposes (IMO) the most useful subset of git commands AND also shows in a single glance all the necessary information about the repo.
I find it very easy to explain git branching / merging / rebasing / push/pull to new people using the tortoise git log view. Basically I'm using the same explanation as the one written by somewhereoutth below [0] but without referring to brambles... I also always stress using git reset --hard to get out of really confusing and bad situations, assuming you had committed first.
Three random complaints about git:
- The fact that it doesn't track renames at all, and instead just makes an educated guess based on comparing the file content. I'm not sure how this could be fixed, though, since git doesn't have a daemon running in the background keeping track of changes. This can lead to the dreaded "modify/delete" or "delete/delete" conflicts. Granted, this would happen less if people would merge/rebase their work branch often instead of accruing commits over time and not occasionally merging from trunk. But it does happen, and it's really unpleasant, it often means that git got confused and it takes a lot of digging and comparisons through history to find out why. Having a gui helps me a lot here but it still a heck of a detective work.
- The fact that there are many workflows and ways to do things and doesn't have a recommended way to do stuff. This can lead to arguments and conflicts, especially between people who have "opinions" (I'm definitely including myself in that group of people!).
This can happen especially with people who switch teams and where the new team works in a different workflow than what they are used to. Actually I've been part of just such an argument this week, it was unnecessary and unpleasant. Especially considering that at the end we both understood each other and agreed that my team's workflow is really not that different than her last team's workflow (for which she was responsible), and our team works under different set of circumstances and with different clients.
- Not specifically about git: Personally I never found it necessary to have a clean history, and I'm confused as to why people think this is important. I certainly don't require this from people in my team.
I review pull requests regularly, and my way of doing that is to run a diff between the start of the feature/bug fix branch and its tip, to see the set of changes introduced by this pull request. I usually don't care about all the "dirty" commits in the middle, although I will look through them if I don't understand something to see how something has developed.
But I never review pull requests solely through the pull request GUI (in github or azure). I fetch their branch locally and do what I just described through tortoise git. It usually takes me only about 30 seconds to generate the diff which lets me see the files changed. Reviewing the pull request itself usually takes far longer compared to this, especially with people who are worked with areas in the code they are unfamiliar with. I write all my notes offline in my favorite editor, and then copy them into the pull request web GUI. I also try to compile and run their local branch on my machine and run the relevant unit tests added by the author to verify they run.
I find the pull request GUI in repo hosting sites to be very ugly and cluttered, and it only shows the latest changes.
So my theory is that people who insist on having a clean history only know how to do review pull request through the web gui, which does show the diffs in the last commit and doesn't show the whole history. But this is probably me missing something or just my 5-person team being small compared to others.
I don't think any of the three problem areas are intrinsic to gui or cli
The rename aspect is a problem in both cases and is related to how git works internally.
Dirty commits van be really useful for the above, do a commit to rename, then another to modify. That keeps the rename operation clean and modifications in their own diff.
For workflow, that is a team process and documentation problem. Every team should document the typical CLI commands for their workflow. Having no documentation around this is negligent, simply referencing some webpage is lazy, it should be spelled out for you
I’m trying to write a helpful reply instead of downvoting. If you use those kind of criteria to determine someone’s knowledge, you’re going to come across as dogmatic, reductionist, etc. I doubt you are really that way, but it’s how it comes across, and it doesn’t make for good discussion. I’d suggest laying out why you think someone’s preference for a gui means they know nothing.
I only use the CLI (because I learned git before GUIs got useable), but my mental representation of branches and commits is *graph*ical, and most of the git user guides and tutorials I see use a graphical representation to communicate git concepts. I imagine it would have been easier to learn git's functionality if I had an interface to git that was closer to my mental representation.