I think there are some legitimate criticisms of Git here. But some of them are...odd. Despite using Git in a variety of circumstances, from a local personal repo project to very large company repos, I admit I haven't run into about half of these issues.
> The closest I have found is the network, which is slow to render (unless it is already cached), does not offer nearly as much details, and scarcely works at all on mobile.
I hope my team never has to consider their mobile device as a way to check the status of a branch. It hasn't even crossed my mind as a use case. Does this come up often for others?
All the time. I would say at least 50% of my code browsing is done from my phone. I make heavy use of the mobile GitHub web interface for this (find-references support has been a godsend, search is still meh, I hate how they keep breaking basic find-in-page with SPA jank). Also Searchfox [0] when I need to comb through Firefox code (fast, excellent, no complaints—well, I guess blame on mobile could be better).
Context: grad student, programming languages and systems research plus a bunch of IoT hacking on my own time. Either elder Gen Z or youngest possible Millennial, depending where you put the cutoff.
Yeah, I can't say enough bad things about the Github refresh. The whole thing feels like it was done by people who've never used git (or any SCM) before. It's not just the find-in-page, it's the navigating branches, text selection, keyboard navigation within a page, and general rendering performance that have taken a huge hit. And, of course, all the side effects of requiring javascript to render text.
I do it when I want to separate out the thinking/understanding from the doing. I might want to mull over how to do something instead of jumping straight into coding, and I find train journeys an excellent opportunity for this. Or sometimes I want to assess dependencies, perhaps I want to choose a library for doing X, I can sit and read through them on my phone and at least get a feel for them and whittle the list down.
Oh that's a good way to put it! I do this as well, especially on commutes or on walks, but sometimes on the couch as well; I have an idea and think about it actively, but to continue my thought process, I have to look at some code, so I open it on the phone.
It always felt weird to get my laptop and look on the "big" screen in those situations, and maybe it's because I just want to think, not to code.
And this is why you should stick to an 80 column limit.
It's only a pain when you decide your codebase is fine with 120+ columns because "everyone has a widescreen monitor" except no they don't. What if I like vertical monitors, or want 5:4 etc.
Having to cater to the absolute lowest common denominator holds back progress. Why should I be forced to adapt your preferred workflow and limitations if I prefer to have a wide-screen monitor or another standard tool.
> Having to cater to the absolute lowest common denominator holds back progress.
Market decided wide screen is better on pc, you blindly followed. Market decided that isn't the case on any mobile platform which in case you missed it vastly out numbers pc.
There was never an argument about whether wide screen is better or not, only that larger column counts make it harder to read your code.
Using obscure single letter variable names also make your code harder to read, is using decent variable names catering to thw lowest common denominator as well, is that a bad thing? Are we holding back progress because we use descriptive names for things?
Make your case about column width, there are valid arguments for longer widths. "Because wide screen is better" isn't one I will accept, last I check no other written media prefers being printed in landscape.
Without implying whether one position or the other is stronger, I want to point out that even when you're on a wide screen it's not uncommon to take advantage of that and have at least two screens side by side.
You are assuming too much about me without having a single clue.
>"What if I like vertical monitors, or want 5:4 etc."
Your choice. Mine - not to work on cell phone. This might change if they will stop crippling smartphones and let it to be hooked to a decent monitors / (future high quality display glasses)
I've tried to extend my work day by checking on projects from the train. Absent spotty data coverage, I've found GitHub works fine and I can do light code reviews easily.
GitHub pulse[1] is a great UI for looking at recent activity. This page is bare for the SQLite mirror because they don't work on GitHub so it only has commit history. The linked Caddy project is a better example. IMO it looks more useful than the timeline.
I wonder if anyone's built the equivalent view for git/GitHub already. Shouldn't be too difficult.
Well, I'm using git to manage my blog. I wrote an Android editor to edit on GitHub and then modified it to work on gitlab. There are lots of reasons but mostly it is because git is impossible to use on mobile, regardless of whether you are using GitHub or gitlab. Checking status is possible but barely anything beyond that.
This write-up really resonated with me in other ways. I wrote a book for O'Reilly about GitHub and still can't wrap my head around git after more than ten years of using it. The points made here resonate with me.
I use git in Termux all the time. It's fine. You just enter commands like normal. I have no idea what the parent to your comment is on about, especially having "written a book".
There's no reason why that feature should not work on mobile. Certainly, it would work on mobile if it was designed/implemented better.
People access github from mobile all the time for the same reasons they access it from any other platform. I've certainly done it.
> I admit I haven't run into about half of these issues
These observations about git are not necessarily "issues." They're more like "value judgements about features." You either agree or you don't, there's nothing to encounter.
There are all kinds of non-optimal optional ways to do things where it's valuable to have the options and have them work as well as possible vs not having the option.
I guess it falls under graceful degrade vs die.
It doesn't matter how much better the proper gold plated option is. If it's the only option then it's fragile and that makes it garbage.
> > The closest I have found is the network, which is slow to render (unless it is already cached), does not offer nearly as much details, and scarcely works at all on mobile.
(The preceding text in TFA makes it clear that this refers to rendering a view of history. This is in a section titled "Git does not provide good situational awareness".)
Here's the thing: if you use a rebase workflow then all history will be linear, and that requires nothing fancy for rendering, and it's fast. That's NOT the reason to want to use a rebase workflow, mind you.
Fossil doesn't have rebase (though it has cherry-pick, which is the building block for rebase), and D. R. Hipp seems pretty proud of this. I understand his and many others' dislike of rebase, but I believe that dislike is founded on some confusion. I believe rebase workflows are -where they are possible- superior to merge workflows, and that linear history is superior to non-linear history.
Let's start with linear history vs. non-linear history. Our brains are very linear, so I think that instantly makes linear history better. It's easy to see that history with lots of branches and merges is non-trivial to understand, and this is much more the case the larger the team of engineers and the larger the number of distinct branches (projects, bug fixes) involved.
For example, at Sun Microsystems, Inc. (RIP) we had over 2,000 engineers working on OS/Net, which is the core of the Solaris and Illumos operating systems. At Sun we had a strict linear history mandate, which meant we were using a rebase workflow long long before Git came along. If we had not had that mandate then OS/Net's history would have been incredibly difficult to visualize since one would need a display that could fit hundreds if not more parallel branches.
If you actually want to visualize history, then merge workflows just won't scale with project complexity.
One might object that, well, for such projects as OS/Net one just wouldn't even attempt to visualize history like that, that one would filter branches of interest and so on. But this comes for free with linear history as with linear history there is no need to attempt to filter what branches get rendered because there is only one branch at all times.
If you care about history, what you really want is to see what's changed over time, and that is always linear. At time t_n you have some commit, and at t_n+1 you have some other commit, and so on. That some are merge commits only obscures the fact that if you're spelunking through history (e.g., bisecting), the history is just linear. All those merge commits do is act as something like text folds in editors, hiding away some sub-history, but if you're looking through it then you really do care about the details and you don't want that history hidden. On the other hand, if you're not browsing through the history, then you don't care if there's merge commits or not. So you should just not care for merge commits at all.
Linear history is just easier to understand. Yes, you want to squash unnecessary commits before pushing to avoid cluttering history with noise -- no one cares about what typos and brainos you made while writing some bugfix or feature commits, and certainly no one will years after you push.
Because rebase workflows lead to linear history, and linear history is better than non-linear history, rebase workflows are better than merge workflows.
But also it's just easier to understand rebasing than merging once you understand cherry-picking. At least for me it is. But I think it should be easier for more people too, if only it rebase were explained that way and explained before merges.
Besides, if you have N commits in a branch and you merge it into another, when you resolve conflicts you won't know which conflicts and resolutions go with which of those N commits, and you won't care, but if you want to understand your work -and also others to understand your work- it seems much better to rebase and resolve conflicts commit by commit.
Getting back to "situational awareness", linear history gives you just that. It's merge workflows that make it hard to be aware of all the recent changes.
> if you want to understand your work -and also others to understand your work- it seems much better to rebase and resolve conflicts commit by commit
I do love rebase workflow and push it everywhere I can. But that's just not true.
Conflict resolution with git-rebase is just horribly implemented. Working even one conflict through a sequence of five commits is so hopelessly repetitive and error-prone operation that it makes a git-merge look almost like a sensible option.
And then the reviewer delays one more day and another conflict appears.
That eiffel tower of context switches does not improve your understanding or anyone's understanding. If it's made sane (LLMs? Yes please!) the git-merge would probably all but disappear on new projects.
Out of curiosity: Was this also with TeamWare/SCCS?
> If you care about history, what you really want is to see what's changed over time, and that is always linear. At time t_n you have some commit, and at t_n+1 you have some other commit, and so on.
Depends on what the history should represent or what you care about specifically, or optimize for.
What landed in the integration branch or was deployed to a singular test environment is certainly linearily ordered on the time scale. What happened during parallel development is rather a DAG. (And even there you could have different working models: clean up (e.g. with git rebase), then integrate; or keep every commit ever made (even if hidden in presentation), fossil-style.)
This has all pros and cons and most of us have their preferences, or even reasons. It should be consistent per project and supported by the tooling.
> Besides, if you have N commits in a branch and you merge it into another, when you resolve conflicts you won't know which conflicts and resolutions go with which of those N commits, and you won't care, but if you want to understand your work -and also others to understand your work- it seems much better to rebase and resolve conflicts commit by commit.
However, with rebasing on top (or squash-merges) you lose the commits in their original context. You may have no merge-commits, but all your commits are merged commits. (They only have one parent in version history, but the file content is the result of a merge, be it automatic or manual.) This may no big deal for things you can and do test for. If finding out a bug later however, it is often easier to comprehend, if one can see or test, if that happened only while integrating the changes. Then you have at least still the working version from the tip of the branch available for comparison.
One could also have a merge for each of the commits (in order), but that does not help with a keeping the history lean.
While I do use git rebase to clean up, I do merge branches afterwards and keep the commits. I usually do my rebases with --keep-base (unless they have been started at a totally wrong branch point) and therefore no integration work with other branches will be done here. That will happen in the merge, to be able to distinguish between what was developed and what was the result if the integration.
Yes. Usually, I come here only for the linked articles and read some discussions, but don't write. But this was too interesting to not comment, so I had to create an account.
> Out of curiosity: Was this also with TeamWare/SCCS?
Yes. It was quite primitive by comparison to git, but it worked.
> > If you care about history, what you really want is to see what's changed over time, and that is always linear. At time t_n you have some commit, and at t_n+1 you have some other commit, and so on.
> Depends on what the history should represent or what you care about specifically, or optimize for.
> What landed in the integration branch or was deployed to a singular test environment is certainly linearily ordered on the time scale. What happened during parallel development is rather a DAG. (And even there you could have different working models: clean up (e.g. with git rebase), then integrate; or keep every commit ever made (even if hidden in presentation), fossil-style.)
At Sun if you had a bug fix you did the equivalent of clone, commit, <any number of fetch and rebase operations>, push.
But for large projects we did something very different. We had a clone of the upstream (OS/Net) for the whole project, and developers would clone the project and work on that. Every few weeks (two or four, depending on the project) the project's gatekeeper would rebase the project clone onto the upstream, and then all the developers would rebase their clones onto the project clone. (Think `git rebase --onto`.)
When a project completed successfully it would rebase one more time onto upstream and push.
These clones functioned as branches. They were archived, but in the upstream there was no evidence left of the clones' existence -- certainly there were no merge commits, as those were verboten.
As you can see, there was no complex DAG in the upstream: it's all linear. The history of the clones was mostly irrelevant, though if really cared (sometimes I did) you could go look at the archives.
> However, with rebasing on top (or squash-merges) you lose the commits in their original context.
Why should anyone care about that "original context"? The project/bugfix delivered. Between the upstream's HEAD as just before delivery, and after, are just the differences contributed by that push, and the commit messages for the commits in that push, and the deltas in each of those commits, are all the context you need.
> You may have no merge-commits, but all your commits are merged commits.
So what?
> (They only have one parent in version history, but the file content is the result of a merge, be it automatic or manual.)
This is like caring about seeing every typo or braino the developer made while working on that code. It's just not useful. Once the code is pushed upstream the conflict resolutions that the author had to do will never again matter to anyone else.
If you wanted to investigate what went wrong in a mishap -a mismerge- you can: examine the downstream clone's history (including reflog). If nothing went wrong, you're done. You can archive those downstream clones (or the relevant bits of their reflog), which, again, we did at Sun precisely for this reason.
If you use a merge flow, those merge commits are forever, and they will forever pollute the history and complicate rendering of history, and they will remain long after anyone could possibly care about what might have gone wrong in a mismerge.
> This may no big deal for things you can and do test for. If finding out a bug later however, it is often easier to comprehend, if one can see or test, if that happened only while integrating the changes. Then you have at least still the working version from the tip of the branch available for comparison.
Ok, so you're concerned about investigations. Again, they're rare, and there's a way to do them without polluting the upstream's history.
Perhaps there could be something like merge commits that aren't commits but annotations that are not part of the Merkle hash tree and which can be deleted, or which are in the Merkle hash tree but hidden, and where if you want to find out the details of what the developer did you still have to go dig in their clones. But IMO that's still mostly pointless.
Thanks a lot, that was quite interesting! Always interested in different ways of doing things and the reasons behind them.
Just to add to your last point regarding hiding history details: that seems to be fossils way of doing it[1][2], if needed/wanted. The history is still in the repo, but the presentation can be cleaned up. (But this part of fossil I only know from the documentation, I have not used it that much.)
> Git puts a lot of emphasis on maintaining a "clean" check-in history. Extraneous and experimental branches by individual developers often never make it into the main repository. Branches may be rebased before being pushed to make it appear as if development had been linear, or "squashed" to make it appear that multiple commits were made as a single commit. There are other history rewriting mechanisms in Git as well. Git strives to record what the development of a project should have looked like had there been no mistakes.
Right, exactly, because the mistakes often aren't interesting. Where mistakes made in development were interesting, then you should write up the interesting details in you code or commit commentary or other documentation.
> Fossil, in contrast, puts more emphasis on recording exactly what happened, including all of the messy errors, dead-ends, experimental branches, and so forth. One might argue that this makes the history of a Fossil project "messy," but another point of view is that this makes the history "accurate." In actual practice, the superior reporting tools available in Fossil mean that this incidental mess is not a factor.
But that's just so much noise! Some devs will make much more noise than others. Devs who commit often, for example, will make more noise. Noise noise noise. If I'm spelunking through the history I don't want noise -- I want signal. Even if I'm looking through history to find out who is a better developer it may not be helpful because some devs will commit more often.
I mean, why not just record your interactive sessions and then play them back when you want to look at the history? Where would the madness stop?
IMO the madness stops at the upstream, where only linear history should exist.
And again, if I want to look at a project's internal history I can look at their archived clone of the upstream. Even in project "gates" (as we called them at Sun) we kept linear history (some projects had very long history, like ZFS and SMF for example). Very few people looked through archived gates -- I did, from time to time, especially the old SEAM (Kerberized NFS) gates from 1999-2000, but not only. Some archives did get lost -- especially really old ones, the ones that matter more to historians than to current developers, so that sort of loss is a problem, but not one that threatens the ability to do work.
> The closest I have found is the network, which is slow to render (unless it is already cached), does not offer nearly as much details, and scarcely works at all on mobile.
I hope my team never has to consider their mobile device as a way to check the status of a branch. It hasn't even crossed my mind as a use case. Does this come up often for others?