So, at least for me, they last around 15 years or so.
But often time when I tell juinors that when they're my age, git will
be distant a strange memory to them, they look at me funny. It's a
wonderful tool and earned its success, but I'll be sad if it's our
final take on the problem.
In fairness, the rate of change of any type of tool slows down over time as the problem domain becomes well understood.
It's like the Joel on Software article (which annoyingly I can't find at the moment) about how software is always pretty much done by about version 4. His example was office software, especially Excel, and sure enough if you loaded Excel 4 today you'd see it does fundamentally all the main things.
I suspect we'll see git last at least double the length of time as those other VCS tools.
I think this is a great point! What even is "git"? If it's the binary program named "git", then there are already lots of replacements for that binary that people use, and it would not be surprising at all if one of those different frontends becomes more dominant than "git" itself.
But if "git" is the protocol, the specification of how a particular construction of a database of versions, then I suspect that will be pretty sticky. I'm sure it isn't the optimal solution but it works well and it's very useful to have a lingua franca for this.
Yes. And the replacement to git might also stay compatible.
(In an extreme case, git can talk svn via git-svn. In a weird alternative history, you could imagine git being treated as a new version of svn; but apart from the names, nothing much else would change compared to our universe.)
I’ve worked with many switches. I have not encountered a 10g switch that will negotiate to 10m. 100m is not automatic in most cases. These very old protocols are very different from modern 10g-100g. So much so that the transceivers may need to load a completely different firmware to even understand it.
Ok. Most of my experience the switches will have 2 modes for each port: 1G/2.5G/10G/25G/100G or 10M/100M/1G/2.5G. This is typical for datacenter switches. Found this out when my trusty 10/100M USB dongle couldn't establish link. I needed to upgrade to a 1G USB3 dongle.
I do think that if there is a replacement to git in the future, it will probably have pull requests, tags, etc. built in that most git servers support but implement separately since they’re not in the standard. Alternatively, GitHub as a platform will become so standardized that they may launch their own “VCS” which is just other things bolted onto git that only work with GitHub (we’re already going there with the git command line)
Excel has recently introduced 4-5 VERY big changes:
* javascript (arguably 'nobody' knows how to use it though, looking at the scarce resources)
* Lambdas
* Sharepoint integration, which is a type of shared notebook - and arguably this has ruined excel usability completely, since linking one file to another is basically unusable, what means were are back to the stone age, where people fucking copy paste things between files (omg)
* PowerQuery (this is not new, but seems to be the way to "fix" the problem that sharepoint files that can be edited by multiple uses are basically unusable junk)
* Updated PivotTable model that allows some basic connections between tables (this all could have been done in multiple other ways before)
For me the problem is that with the "multiplayer Excel" that seems to be promoted by Microsoft (shared workbooks on sharepoint, where multiple users can edit them at the same time), Excel lost the main functionality for actual power users, who take data from multiple source files and then consolidate them to one final report. Of course this is still "possible", but not as easy as it was before with shared drives.
I see like multiple major regressions at Microsoft that harm "average" office worker productivity now:
1) Excel file linkages broken (as described above)
2) Outlook calendar app on android -> lack of ability to have a custom notification sound (e.g. a 30 second sound), so you can skip fucking reminders, because one "ping" is easy to miss. Why cant I have a fucking calendar reminder that actually reminds me about stuff with sounds?
3) The "new" windows taskbar that combines instances of same program into one button. Do they assume that most users treat windows like a toy? Nearly every office worker has like 3-5 excel files open, 3-5 emails, maybe some PDFs - and has to switch between them. Due to the fact that taskbar is combined by default, incredible amounts od productivity are lost
4) Hibernation is hidden. So you are supposed to turn off your computer every day, then come to the office, wait for 10 minutes for it to turn on (all the antivirus, constant updates, VPN), then turn your programs back, then turn your files / emails back. So you waste another minutes to setup the computer back to work. Compare it with hibernating, where you get your work back exactly the way you left it the day before. (and yes I am aware that updates are important and so on, since they defend against zero-days, but a multi-billion dollar company has the resources to figure out how to do them without productivity loss)
5) Bonus points: your computer can wake up at 3 am to install updates and also wake you up (maybe they changed it recently, or maybe admins control this by policy)
6) Random shutdowns, because some update is so incredibly important that at least once per quarter they have to force you to turn off your computer. Bonus points are when a window pop-up "restart now" and "ok" is the selected default so you accidentally press it while typing (and yes, I do restart my computer at least once per week to get updates)
However Microsoft is no longer interested in doing any productivity studies. They dont care. Now it seems their main goal is to offshore development to low cost countries. So we get software that looks as if it was done by lowest bidder.
I wonder why there's no true modern replacement for Excel that preserves the same versatility and ease of use for nontechnical users.
Every user could just have their own file, in which they could stash records(Or updates to other people's records), and you could have interfaces to view the data that look like a typical spreadsheet.
The data itself could live in an unsorted set of JSON objects with UUIDs, but the UI could be just as easy as Excel, you'd get tables that you could add or remove columns to and from, and put formulas in the fields, and query in some stripped down language with similar power to Excel.
And it could be 100% compatible, you would be free to put your data in the spreadsheet like the old fashioned way, sync with any cloud including SyncThing and no cloud at all, and data files could just be plain CSV you could version.
Linking two Excel files and consuming data between them requires the workbooks be open in Excel.
Power Query is no where close to what you described it as. It was not created for SharePoint or real time coauthoring. It is for getting and transforming data.
Subversion is basically CVS done right. The problem is that CVS was a dead end that didn't scale to a distributed development model.
Git goes back to the local RCS model and adds atomic commits to that model. That's how it climbed out of the local optimum that was Subversion. There were a couple controversial choices that Git made, for example not tracking renames and not having linear revision numbers, but they turned out to be not a big deal and they allowed very efficient operations without the performance issues of e.g. darcs.
Given all the attempts to fix version control between 1995 and 2010, the basic data model of git seems to be very hard to improve on, especially with additions such as git-lfs.
There could be new command line interfaces but it has become harder and harder to kick away the incumbents. I know no one who is using git switch and git restore instead of the overloaded and confusing git checkout.
git-lfs is horrible, at least it was horrible the last few times I tried it out.
More precisely git-lfs is horrible the way it works with Github and its insanely low git-lfs storage and transfer limit.
What ends up happening inevitably is that you add some file to git-lfs that you did not mean to.
Only half sane/insane way to fix this is to just say screw it and start a fresh git repository, hopefully with files that you salvaged before the whole git-lfs mess.
I am quoting Github documentation "To remove Git LFS objects from a repository, delete and recreate the repository."
> I know no one who is using git switch and git restore instead of the overloaded and confusing git checkout.
Welp, I guess there's me, but it does indeed seem like adoption of the new commands hasn't been very forthcoming - I guess that's what happens when "the old way still works just fine" - but personally I'd expect that more and more people will change to the new commands over time.
I just checked these commands out to update my git knowledge, but when I saw the following in the docs [1][2] I immediately marked these commands as not (yet) worth it to learn since the way these commands work might change.
THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.
So that might have something to do with it as well.
Especially if there are stable commands that I already know that have the same functionality.
It makes sense for old timers to keep just doing it the way we always have, but I wonder how newcomers to version control are being taught. I would really hope they aren't just being thrown a bunch of these inscrutable commands by their leads, like when I learned it!
Judging by my colleagues (whether more or less experienced than me), "whatever the GUI allows for".
Yes, almost the entire company runs on the subset of git presented by Visual Studio and Azure DevOps. I would guess this is more and more common, and even the more obvious shortcuts available for many things through git itself will become more and more arcane.
I should at some point alias git checkout to throw a warning, git switch/restore are clearly a better choice, but unfortunately checkout is ingrained in muscle memory at this point.
I, personally, would find this very helpful if git did it by default. I learned git by searching for "how do I?" stuff. Now I know how to do things, so I don’t go looking. It's possible that there are new and improved workflows, but I'll never know because it already works for me, even if I do it "the hard way".
I for one am trying to train myself to start using switch and restore, so that I can recommend them in company channels for people having problems with our monorepo(s).
> Given all the attempts to fix version control between 1995 and 2010, the basic data model of git seems to be very hard to improve on, especially with additions such as git-lfs.
I wouldn't be surprised if some of the work and rigour being invested in OTs and CRDTs, and multi-user collaborative editing in general leads to some breakthrough improvements in the source control space too.
Aren't CRDTs the logical conclusion of automatic merging? I feel like with source control you want to be more intentional about what gets merged, right? Maybe CRDT can be good for trunk-based development with a merge queue. Definitely has a spot in pair programming.
I don’t know what we’ll be using 15 years from now. But the thing that is really sad in your list is that you stopped using mercurial in 2015, but still use git to this day.
I migrated a project from clearcase to git at my first company and for all the hate I have for clearcase even I agree there was little point in switching to something else before. We had a bit of svn on other part of the company but that was it.
VCS don’t change that fast. All the tools you list before the advent of DVCS actually have a lot in common. I think git will be there for some time.
The internet tends to lock things in. There were many languages dominant in history at some point or another, english will be the final one. There were many scripting languages, javascript will be the final one. Many networking protocols, TCP/IP the final one. Same for git. I think the only thing that might displace git is some environment for new programmers with its own version control system like glitch[1].
> There were many scripting languages, javascript will be the final one
If, by “scripting languages”, you mean “browser-native languages”, WebAssembly might become a serious contender as the lingua franca for the Web in the long term.
More generally, a globally connected civilization locks things in, once they are sufficiently widespread.
Barring an apocalypse, our present is eternity. I'm always amused when I read science fiction that assumes in the future, Chinese will be the lingua franca, or that we'll have political offices modeled after Ancient Rome, or that there's a world government, or similar nonsense.
To paraphrase O'Brien from 1984: "If you want a picture of the future, imagine a crony-capitalist, meme- and outrage-driven society that always seems on the brink of collapse but never actually does collapse – forever."
Generally git‘s support for a stacked PR workflow is poor [0], but imho that is the future of team collab (git is great for very asynchronously built projects, like the linux kernel).
I also wonder, how much better git could be if it was based on DAGs not trees (I may want to use a changeset that is still developing in more than one branch without maintaining copies of it) and corollarily I‘d like to rebase subtrees (sub-DAGs) instead of single branches.
I have introduced a stacked PR workflow to our team a while ago and a few months later half of the team had migrated to some kind of stacked PR workflow tool (on top of github and git, even though support is sub-optimal).
It seems like this is an idea that is really sticky.
> (I may want to use a changeset that is still developing in more than one branch without maintaining copies of it)
Not sure if you realize, but a commit is a state of all files in the repository, not a patch. Patches are calculated for you at display time (and can be calculated against any other commit, not just a parent). Sounds like you may be confused because of trying to apply a wrong mental model of how the repository represents things.
I'd say that git actually supports stacked workflows quite well. It's GitHub's PR model that makes it hard.
> I'd say that git actually supports stacked workflows quite well. It's GitHub's PR model that makes it hard.
I agree that the model does but I’m not aware of any good way of using such a workflow with the CLI either. Is there a reasonable way to effectively keep rebasing on top of multiple upstream branches?
> Is there a reasonable way to effectively keep rebasing on top of multiple upstream branches?
This is the problem. You cannot rebase with a stacked PR flow. The correct way to do this is use the merge command as intended.
One of the most powerful features of git is the ability to understand a common history between multiple parties and everyone throws this away entirely with a rebase and causes non-stop conflicts. I simply do not understand the preference for it, especially in shared repos.
Do not use a rebase workflow with any work that is shared with others unless you are communicating regularly and understand how obliterating your commit history will change how git views what is changed between two repositories. Rebase only works well if you are in a leaf branch you control and even then I prefer a single squash merge back into upstream rather than multiple rebases if possible.
I can't even tell you how much of my life has been lost correcting merge conflicts caused by bad rebasing of my commits by others.
> Not sure if you realize, but a commit is a state of all files in the repository, not a patch.
I think that's a core problem. It's not just that git calculates a patch to show you, it's that — in every git-using project I've seen — a developer writes a patch, and writes a commit message describing that patch. It's not just github. And then developers make the incorrect assumption that git's later presentation of the commit as a patch matches the original patch and is accurately described by the commit message.
The developer never writes a patch when using git. The developer creates a new repository state, links it to a parent state (or multiple parent states) and describes the difference between these states in the commit message. A patch form is just a handy way to visualize these changes.
You can dump commits into patches and then apply them onto different repositories, but in order to do that you still have to convert such patch into a new repository state first.
Many people "learn" git by learning which commands to use to do some things and in turn don't understand what's going on at all. It's like learning how to write a letter by reading Word's manual.
> I also wonder, how much better git could be if it was based on DAGs not trees [...]
Git generally supports DAGs.
> [...] corollarily I‘d like to rebase subtrees (sub-DAGs) instead of single branches.
Rebasing is something you do to the commit graph, which is a DAG. Branches only come in incidentally. Branches in git are really just mutable pointer to immutable commits.
What you are describing is probably some useful workflow, I guess?
I seem to understand GP wants to move a whole DAG potentially having multiple leaves, not just a DAG ending at a single leaf.
IOW
git rebase --onto shaX shaY shaZ
ends at shaZ, git walks backwards from it until the commit whose parent is shaY to produce the list of commits to cherry-pick onto shaX
So presumably this would be useful:
git rebase --onto shaX shaY [shaZ1 shaZ2 shaZ3 ...]
with shaZn being optional and consisting of all leaves down from shaY
This is achievable with git but it's not just doing n rebases like so:
git rebase --onto shaX shaY shaZ1
git rebase --onto shaX shaY shaZ2
git rebase --onto shaX shaY shaZ3
...
because each rebase would produce different commits for parts that are common to shaZ n1 and shaZn2 ancestry, so one would have to first find all the branching points and do partial rebases onto the rebased parent commits in order.
It definitely can be done (manually or automatically) but is not as trivial as one might think.
Yes, and the original commenter's point is that git does not support this well, at the data model layer even. Because commits have exactly one parent commit, which is immutable, and because rebasing creates a new commit, rebasing an entire subtree with N nodes under it requires N operations, rather than just 1.
Personally I think it's a pretty small price to pay for the advantage of the single-immutable-parent model, but I do think it's surprising that there aren't better tools for this workflow. I do this all the time, but manually and painstakingly.
This is not true, merge commits are commits with > 1 parents (octopus merges are merely commits with > 2 parents)
But indeed since the parents commits are part of the computation of a commit's sha then by design changing the parents means changing the commit's sha, which is a very nice property to have.
That said, the model has what we said as a design consequence, but it's perfectly workable to have tooling that walks history and finds branching points and whatnot. Git does it all the time with existing porcelain commands, and I've done it in different contexts (e.g to produce diffs between tip and branching point, analysing which files have changed, and take action pertaining only to these file changes and their dependents) but the gist of it is the same.
It's merely a matter of such porcelain commands not being implemented and not being part of upstream git, so everyone either does it manually or invents their own tooling when they're sick of the pain point.
I can't edit anymore, but hopefully people can read my comment with s/commits have exactly one parent/non-merge commits have exactly one parent/ :)
But this did make me realize that the problem with this workflow isn't the "one parent" part at all, it's really just the "immutable parent" part.
But to the main thrust of your comment: Yes, this "porcelain" is what I meant by my surprise that there aren't better tools for this. I think the reason there aren't is that it is really hard to do this well with porcelain, because of requiring a bundle of modifications to the commit tree, where there is no good way to make the whole bundle atomic. So it works fine (and I have a script for it) in the happy path, but it becomes a bit of a nightmare if something doesn't apply quite right.
And that's what I mean by this being unsupported at the data model level, that there is no way to do atomic operations on subtrees as a whole.
> [...] where there is no good way to make the whole bundle atomic.
You could just do all the commit manipulations you need to do, and only update the branches at the very end?
Updating the individual branch 'pointers' ain't atomic, but if there's nothing else going on in the repo at the time, it can't really fail; if you've already created the new commits.
When things like this usually go wrong with an automated tool, it's not that it "fails", it's that it succeeds part of the way, leaving things in an inconsistent state, which is then hard to reconstruct in either direction.
But you're right that it should be possible to build such things in a way that works well and very rarely screws up. But just that I don't really know of any tools that try to do anything more complicated than `rebase -i` seems to suggest that it is not easy to do, or there would be more people doing this.
> When things like this usually go wrong with an automated tool, it's not that it "fails", it's that it succeeds part of the way, leaving things in an inconsistent state, which is then hard to reconstruct in either direction.
I can see that things can go wrong when your are half-way through constructing the new commits. But that's fine: you just leave them as they are, and let git's gc clean them up eventually automatically. As long as you don't touch the user's branches (remember, which are just mutable pointers to immutable commits), the user doesn't need to care that your tool screwed up half-way through.
Yeah I'm with you, this can be done, but again, I'm wracking my brain for an example tool that does this without being frustrating sometimes. Even just rebase itself, which is much simpler than what I'm talking about here, has footguns.
But I think this thread has convinced me that someone could almost certainly make better tools for this stuff, and now I'm just wondering why they haven't.
I realized the multiple parents thing was a total red herring. It really is just the immutability.
What I was thinking of was having multiple parents over time rather than at the same time like a merge commit. But that would just be one (not immutable) parent but with a history of what that parent was over time, not "multiple parents".
Not only it's useful, it's as easy to do in git as typing `git rebase -r`. Recently it even gained support for rewriting branch pointers in the process.
In general, it's almost always better to use long options. So that would be `git rebase --rebase-merges` in this case.
Almost always means: it's better eg when communicating with other humans, whether that's on a forum like HN or in code or scripts. Long options are easier for humans to understand and to 'google'. They also provide some redundancy against typos.
The sole exception, where short options can be useful, is when you are actually using a command line interactively. Use short options to your heart's content there.
I suspect it’s the opposite way around: most people, when they hear “git”, macroexpand it to “github” and don’t even know that there is a (more powerful) command-line interface.
The peer-peer distributed nature is barely known — these days it’s a centralized client/server system. I remember the Internet connection going out at work a few years ago and developers saying they couldn’t coordinate bc github was not accessible when they could easily have synced, merged etc with each other directly.
My partner definitely does not know the difference between Git and GitHub. He's not much of a programmer but yeah.. maybe this is like Java vs JS all over again. Or jQuery vs JS. That one makes me extra sad.
I think git gets a bad rep because no one can agree how to use it.
GitHub PRs vs pushing a branch, rebase vs merge are just two examples of tools that do identical things in fundamentally different ways.
And the problem is none of them are wrong. Rebasing minor commits simplifies unnecessary complexity in your history. Merging preserves what actually happened which can provide insight into why changes occurred. Of course reverse merges are the worst but that is a can of worms...
When pushing to a branch you can never force push but you always force push a PR branch...
Hell sometimes the easiest things create unsolvable rifts. I know of the main repo as origin and fork for my fork. Some have learned that the main repo is upstream and origin is your fork.
Neither is necessarily wrong but good luck being clear when origin can refer to two locations with such extreme use cases.
It's very much a "glass half full" perspective, which gets tiresome from somebody like Bjarne who is very resistant to the idea that he's made mistakes. It excuses lots of bad mistakes because hey, if people really felt that way they wouldn't use C++ right? But of course increasingly they aren't using C++ because it sucks, which is why they were complaining.
Unlike C++, Git has put considerable work into responding to complaints, understanding that while yes, they wouldn't complain if they didn't use it, they also wouldn't complain if there weren't so many things to complain about. Lots of things we use every day don't get many complaints because there's nothing much wrong with them. Even the brutal Git command line is less hostile today than it was originally.
I feel like you are being a bit unfair to Bjarne to to my knowledge isn't so much saying "we didn't make mistakes" as much as "we didn't make mistakes we should fix".
C++ is the juggernaut it is because it just works. Your antient C++ codebase doesn't need many changes to get up to date on a language level.
That doesn't mean it is painless to update toolchains but it does mean that the language isn't making that pain worse.
As part of maintaining this the bar for breaking old code isn't "we shouldn't have done that" or "we wouldn't have don't that" but something more like "almost all code using this is wrong anyway".
Most critiques of C++ do not raise to that level and so aren't fundamentally needing to be fixed.
Bjarne is quite happy to admit that we made mistakes, but that wasn't my criticism was it? I'm saying that Bjarne doesn't like to admit that Bjarne made mistakes.
You can't be vague and make your point here. I explained a category of "mistakes" and you simply repeated your point.
To be clear my point wasn't about who made the mistake but that some categories of mistake aren't fixable. Oftentimes people conflate "don't change it" with "it wasn't a mistake".
Found an "I made a mistake" that is very explicitly self owned. Finding counterfactuals is nearly impossible so going to leave it at that without more specificity.
> Unified function call: The notational distinction between x.f(y) and f(x,y) comes from the flawed OO notion that there always is a single most important object for an operation. I made a mistake adopting that. It was a shallow understanding at the time (but extremely fashionable). Even then, I pointed to sqrt(2) and x+y as examples of problems caused by that view. With generic programming, the x.f(y) vs. f(x,y) distinction becomes a library design and usage issue (an inflexibility). With concepts, such problems get formalized. Again, the issues and solutions go back decades. Allowing virtual arguments for f(x,y,z) gives us multimethods.
Yes, Bjarne wants Unified Function Call Syntax, he has wanted UFCS since at least the 1990s, years prior to C++ 98 but was not able to get WG21 to standardize it, not least because there are a bunch of tricky questions you need to answer to add UFCS and Bjarne's answers are... not the ones everybody else prefers.
The paragraph you're citing is from C++ proposal P1962, in 2019 - it's Bjarne basically arguing, as usual, that he should get his way and blaming the committee for the resulting problems. In that section Bjarne says that OK, he has just spent an entire paper telling people that they shouldn't have the certainty they do, but why defer to him, surely he can be wrong too? This is the sole example from that text where he admits to any mistake, over 25 years ago, and he blames everybody else for the mistake anyway saying it was "fashionable" to do this even though he pointed out the problems.
We should distinguish between problems which actually aren't fixable and problems which it was decided not to fix, I don't see a lot of the former in C++, but I do see a lot of the latter. And decisions can be changed.
Reminds me of what Bungie said in one of their GDCs. They don’t mind it (too much) if people get heated on their forum or subreddit, because people who care about Destiny are the ones that get worked up. It’s when most stop complaining or praising that they get worried, because it means apathy has set in.
This is a bit of wisdom that is easy to miss when you are developing a product. When people are getting worked about something and are very vocal, positive or negative, it means they care in some way. Instead of going into the doom spiral of “nobody likes what I’m building,” you can reframe it to be, “people are very passionate about what I’m building,” which is a better way to start the discussion of how to make what you have better.
YoshiP director/producer of FFXIV from Square Enix said the same thing.
"3. Learn to listen and adapt. A complaint is worth twice a compliment. The silent always leave first. If citizens are complaining, it means they still care."
A philosophy that has helped me: Do what makes sense for your immediate goal and then reassess and adapt.
In practice, I actively rebase my commits in a PR with the sole focus of "What will make this easiest to review?". Then, once the review is completely I ask "What will make this easiest to operate and understand in the future?" I might squash everything together, or I might restructure into independently deployable pieces to facilitate rollback.
The point is that all these things might have different needs and it's ok to do different things at different times. But that's requires a little more judgement from individuals and is difficult to teach and enforce across larger teams.
It's important to distinguish between 'local disagreements' and 'social disagreements'.
The former are things that don't affect anyone else. Eg your co-workers don't care if you your remotes 'origin' and 'upstream', or 'fork' and 'origin'.
The latter are things you need to coordinate on with other people. Eg how you want your git history to look like in the end.
> if apple designed git's cli it'd be bilion times better from ux perspective while only 10% less powerful I guess
Why then does every dev I am aware of who use Apple start by installing Homebrew?
Also, you are talking about the same Apple that has a menu system that closes the menu if you click at a submenu?
I mean, it breaks at least two reasonable assumptions:
- clicking on a branch node would work on the branch like clicking on a leaf node affects the leaf
- clicking the menu works like everywhere else
Or the same Apple UX where, if I opened a dialog in my browser I cannot use the same browser to look up in the wiki where on the file server I am supposed to find a certain file I am supposed to upload?
Or the same Apple UX where there is a different shortcut depending on whether I want to switch between windows of the same app or windows from different apps?
The same Apple UX where I had to learn from application to application which features were in the menu and which were hidden under one or another gear icon?
That said, I am considering another for my next laptop.
> menu system that closes the menu if you click at a submenu?
Mine doesn't do this, unless I'm misunderstanding what you mean by submenu (I'm thinking of the thing that has a > at the end. Also why would you want to click it when it opens automatically on hover?)
> if I opened a dialog
So close it, or look up the thing before you open a modal, a rather common concept across many platforms.
> there is a different shortcut
Granularity is bad... why exactly? But a tip, get HyperSwitch (this is the real reason for writing this comment)
The last one I don't even get how you mean the OS designer would get involved with how exactly applications are made. What would the alternative mechanism be, forcing (how?) them to put everything in menus? What about right-click menus, should they be banned? How is any of this unique to Apple?
I'm not saying they are infallible, but these are some weird ass examples.
> Or the same Apple UX where there is a different shortcut depending on whether I want to switch between windows of the same app or windows from different apps?
That one is on purpose, and I vastly prefer it to (what I presume you are implying) the "alt-tab across every window in the universe". I'm delighted that even Ubuntu now honors the alt-backtick versus alt-tab distinction, although I'd bet that is configurable, which is likely what you're asking for, too
My experience is that the Windows windowing system supports keyboard navigation through the UI elements much, much more than Apple (and often Ubuntu, too). I do prefer that, but not enough to use a vastly inferior OS that just happens to have strong keyboard UI navigation support
> My experience is that the Windows windowing system supports keyboard navigation through the UI elements much, much more than Apple (and often Ubuntu, too).
That's due to historical reasons. While both X11 and Apple could assume the presence of a mouse, it was an optional add-on for a PC back in the MS-DOS days; the original 16-bit Windows had to be fully usable even in the absence of a mouse (the only thing which came with Windows and didn't work without a mouse was the image editor Paintbrush). A lot of that keyboard-oriented legacy still survives in the Windows API.
What a perfect comment: it’s impossible to conclusively declare it snark (unwelcome in HN comments) or a simple observation of fact (desired in HN comments).
Shakes head: oh Apple, can’t live with you, can’t live without you.
I'm glad Fossil works for them, but this line is bothered me:
> In contrast, Fossil is a single standalone binary which is installed by putting it on $PATH. That one binary contains all the functionality of core Git and also GitHub and/or GitLab. It manages a community server with wiki, bug tracking, and forums, provides packaged downloads for consumers, login managements, and so forth, with no extra software required
git, for all its issues, is not bundling the kitchen sink. I do prefer the "do one thing and do it well" approach.
Git actually is bundling a lot of stuff you probably don't realize. Run 'git instaweb' for example and it will spin up a local CGI server and perl CGI script to give a very simple web UI: https://git-scm.com/docs/git-instaweb Fossil isn't much different in core functionality here.
There is a ton of email client integration and functionality in git too that most people who only use GitHub probably have absolutely no idea exists or even why it's there. Stuff like sending email patches right from git: https://git-scm.com/docs/git-send-email
I tried that (primarily because I didn't know about it and was excited), but it didn't work. It needs me to install "lighttpd" to work. And the steps to install that are not straightforward.
I like that a lot of functionality is not bundled up in the git that I have already installed in my computer, but at the same time, I agree with the fact that adding these separate binaries is not easy as a user.
Wow now that's a blast from the past. That's a nice relic from the times of people getting annoyed with Apache's one process per request model and Nginx not being popular just yet. Does anyone use that anymore for, well, anything?
Yes, which is why git is a pain in the butt to install and you have to rely on your OS packages (which includes all the kitchen sink stuff) or a GUI installer with all the necessary dependencies vs. Fossil which is just download executable and done.
Securing the software supply chain for software updaters and VCS systems means PKI and/or key distribution, cryptographic hashes and signatures, file manifests with per-archive-file checksums, and DAC extended filesystem attributes for installed files; Ironically, there's more to it than just `curl`'ing a binary into place and not remembering to update it.
I'm a Linux person but often at work due to decades of Gates's effective brainwashing I almost always have to use windows on the desktop. IBM was the only exception. That said, on windows, all I do is get this https://git-scm.com/download/win run the installer and yes it installs stuff but it's literally all automatic. So it's easy on Windows and on Linux, Mac I don't know, I don't do Apple products.
From that page: "Git for Windows provides a BASH emulation used to run Git from the command line. *NIX users should feel right at home, as the BASH emulation behaves just like the "git" command in LINUX and UNIX environments."
That's correct, it works automatically and is great to fix windows (when I have to work on windows) so it has some functionality but even if all I used out of that was git, it's easy. Is it all one exe? No. Does it need to be? No.
CLI and GUI are different languages that are optimal for different use-cases. A dev who doesn't understand that and refuses to use CLI where appropriate is like a dev who would refuse to learn English. They are crawling when others can run.
The first Microsoft OS was a UNIX variant called Xenix "The first operating system publicly released by the company was a variant of Unix announced on August 25, 1980. Acquired from AT&T through a distribution license, Microsoft dubbed it Xenix": https://en.wikipedia.org/wiki/History_of_Microsoft
Windows NT only got the bare minimum POSIX support for Windows NT to be allowed into DoD contracts. It was barely improved from there, and its SUA replacement was hardly any better.
Mostly ignored by Windows developers and finally put to sleep in 2003.
Xenix, which was actually my first UNIX experience, predates Windows 3.x success, and was largely ignored as Microsoft decided to focus on MS-DOS and OS/2.
WSL exists, because Microsoft realised plenty of people don't care about Linux, and rather buy Apple hardware for a POSIX experience, and since Linux kernel ABI matters more than POSIX in modern times, so WSL it is.
One needs to sell that Linux Desktop experience, that is taking decades to move percentiles.
None of that is relevant for Windows developers targeting Win32, and .NET technologies, the crown jewels.
These is exactly what my first thought was! Installing open-ssh and git is kind of my first activity on a new computer.
But I believe they are talking about setting up a git server. The thing that we rely on GitHub/GitLab/Bitbucket for. Richard counts them as an added dependency.
(I mean, he is not wrong in being worried about that. You are basically giving your all your code to a company. Which does not matter for open-source projects like SQLite, but it does for many private projects with code as their primary IP)
What is a “git server”? There’s no distinction between client and server in git; you can “git pull” from any machine with the normal “git” program installed that you have SSH access to.
Who uses git-daemon these days? When's the last time you saw git:// in a README?
Practically all use of git is either the "smart HTTP" protocol over HTTPS, or over SSH. git-daemon is plaintext, you wouldn't want to push over that, and for public use HTTPS has won.
I believe grandparent means what is these days called "forges", a web frontend with user accounts and such, with an extra heaping pile of features.
I’ve been trying to install git on the hypervisor of my smartOS install intermittently for a year. I run into system package conflicts or key signing errors and then I give up and switch to a zone that isn’t so borked with package issues.
Then I go lament in the corner that I really should be serious about migrating this to 200TB home lab to anything else and then realize that the 200TB is not something easily backed up in the case FreeBSD or TrueNAS doesn’t understand my Zpool versions and all of those zones I created will need to be rebuilt as jails…
And my lamentations turn to tears. All because I wanted to just checkout some random project.
Come on, isn’t that kind of an argument from the 90ies, when disk space was scarce, and internet connections slow?
I mean like, I have space for millions of kitchen sinks now. Considering that, I kind of refuse to accept that out of all things, bundle size is a valid distinction criterion for VCS‘es.
Git send-email is actually the best email client I've ever used. It's the only reason I managed to post to mailing lists. I couldn't figure out anything else.
The concept that you can isolate "one thing" and it's not in itself "a set of other things" is a very nasty myth in the world of programming. Everything is composite. Everything is a pipeline of commands. Made of things. The "job to do" is in the eye of the beholder, not absolute. The "single responsibility principle" is not applicable in reality. It's always a tradeoff of maintaining a balance of cohesion and modularity. Where we make a cut and call it a "thing" is up to us and our needs.
For many people, for example, the tools of GitHub are so integral to their workflow, they can't use Git alone at all. So to them GitHub is the "one thing". So SQLite has their own "thing".
They're not saying it doesn't encapsulate more than one thing. They're saying *at the abstraction level of "stuff you need to install and run" it is one thing.
I think SQLite is fantastic and Richard is obviously a genius. But I always found his obsession with single binary monoliths odd.
As you mentioned it goes against the Unix philosophy of do one thing and do it well. To me it's obviously cleaner to divide a system into components that can later be swapped or modified independently.
I have no idea why Richard focuses on such things but:
I'm old enough to remember when developers spent time making sure they could plow all of their build assets into a single binary distributable. It often had kind of a zest to it and when you dealt with software had directories full of stuff it looked both "corporate" and "sloppy".
I've never quite gotten over the feeling that the piles of dynamically linked libraries hasn't helped things. I know objectively that there's a notion that you can update libraries instead of applications, but it feels like it makes updating applications fragile and you inevitably end up in some kind of dependency hell. "But breaking insecure applications is a feature!" I mean, okay, I guess. But I still need something to work and don't want to spend all day fixing broken layers of dependent stuff. If I have to do that, I may as well just update a single binary.
Go seems to have come back around to this style of thinking, and in a sense container images and JAR files are often trying to replicate what it's like to just download a binary, chmod +x it, and execute it.
Directories full of stuff is similar to websites with URL paths like "/site.php?page_id=18231238". Or even better when subdomains get involved and it looks like "secure3.action.domain.com/admin.php?page=123424". It technically works but is a bit ugly.
Also another web analogy might be dynamic linking being similar to microservices. People want to build and ship smaller components that can be swapped out independently. It works but does seem to make updating and testing fragile. You can test heavily at the boundaries but there's still kind of an "air gap" between the main app and the lib/microservice. If you want to be really sure there's no breakage, you have to test the whole thing, at which point you might as well just ship a monolith.
>Directories full of stuff is similar to websites with URL paths like "/site.php?page_id=18231238". Or even better when subdomains get involved and it looks like "secure3.action.domain.com/admin.php?page=123424". It technically works but is a bit ugly.
OOC, why does this stand out for you? Just to explain my curiosity, I've worked on Mac since I was a kid starting with System 6 and then going to OS X when it came out, so Apple's "your program is all in that file" just kind of made sense to me and it was really convenient to just drag a file to the trash and the app is _mostly_ gone, minus a few .plist and other config files in ~/Library.
But I _like_ the old forums and sites that still show the stuff like page_id=N; for the boards and forums I go to, it's very useful to just jump around long topics or you can play with it on your shitposting.
Plus most modern browsers truncate or hide the full URL anyways; I dislike this feature personally, but at least Safari's concise tabs are a good balance for someone like me.
Fair enough, for message boards it's fine. I think I was mostly just thinking about old/sloppy WordPress sites where you might click on "about us" and it takes you to ?page_id=1234. Feels like a lack of attention to detail compared to /about-us. Similarly, a binary surrounded by a bunch of folders and dlls feels like a lack of attention to detail (and thus kind of "corporate" as the previous poster mentioned).
Dynamic linking is the bane of backwards compatibility.
Now everything is containers, appimages, flatpacks, docker images and so on, and all they do is pack all the libraries a binary may need, in a more wasteful and inefficient format than static linking.
In that sense, we truly have the worst of both worlds.
The situation on windows is fascinating: everyone links these libraries dynamically, and yet, there are about two hundred of them on my system, every application using its own uniquely outdated version.
In my practical experience the set of things that can go wrong if you link apps dynamically is much larger than the problems that arise when they are statically linked.
For one, it is more complicate to keep track of which of the many shared libraries on a typical system are used by which application. It is common that the same library occurs multiple times in different versions, built by different people/organizations and residing in different directories.
Quick, without looking: which TLS library do your network exposed subsystems use, which directories are they in and where did you install them from. When you do go to look: did you find what you expected?
Have a look at all the other shared libraries on your system. Do you know which binaries use them? Do you know which versions of which libraries work with which binaries? Do you trust the information your package manager has about version requirements? Does it even have that information?
Then there's the problem of what happens when you upgrade. The servers you run might have a rigorous battery of tests. But now you are running them with libraries they were not tested against. Sure, most of the time it'll work. But you don't know that. And you have no way of knowing that without downloading, building and running the tests. Or have someone else do that.
I've been in the situation where someone inadvertently updated a library in production and everything came crashing down. Not only did it take down the site, but it took a while to figure out what happened. Both because the person who did it wasn't aware of what they'd done. And the problem didn't manifest itself in a way that made the root cause obvious.
The clearest risk with statically linked binaries is if they are not updated when there is, for instance a security problem. But in practice I find that easier to deal with since I know what I'm running, and for anything important, I'm usually aware of what version it is or when I last checked for updates/problems.
> For one, it is more complicate to keep track of which of the many shared libraries on a typical system are used by which application. It is common that the same library occurs multiple times in different versions, built by different people/organizations and residing in different directories.
That's not common at all, man. I strongly recommend you don't do that.
> Quick, without looking: which TLS library do your network exposed subsystems use, which directories are they in and where did you install them from.
Openssl 3.x.y. It's /usr/lib64/openssl.so or similar. They are installed from my distro's repository.
> When you do go to look: did you find what you expected?
Yes. Openssl 3.1.1-r2. The OpenSSL binaries are actually named /usr/lib64/libssl.so and /usr/lib64/libcrypto.so. Upstream version is 3.1.2. There have been two low priority CVEs since 3.1.1 (never change openssl...) and my distro has backported the fixes for both of them into 3.1.1-r2.
> Do you know which versions of which libraries work with which binaries?
What do you mean "which versions of which libraries"? There's only one version of each library. If the package manager needs to keep an old version of a library around, it gives a loud warning about it so I can either fix the problem or ignore it at my own peril.
Those two .so files (libssl.so and libcrypto.so) as used by postfix, dovecot, and nginx. They are also linked by opendkim, spamassassin and cyrus-sasl, but those don't have open ports on the internet, so they don't really count. OpenSSH can optionally link to openssl; as it happens, my openssh does not link against a crypto library, openssl or otherwise. It just uses openssh's built in crypto schemes.
> Do you trust the information your package manager has about version requirements?
Yes.
> Does it even have that information?
... wat..? Of course it does?
> I've been in the situation where someone inadvertently updated a library in production and everything came crashing down. Not only did it take down the site, but it took a while to figure out what happened. Both because the person who did it wasn't aware of what they'd done. And the problem didn't manifest itself in a way that made the root cause obvious.
I've been in the situation where a security guard at my last job inadvertently discharged his service revolver into a Windows machine, and it crashed. That doesn't mean I stopped using Windows. (I mean, I did stop using Windows...)
That's genuinely just not a problem that I've had. Not since 2004 and all the C++ programs on my computer broke because I force upgraded from GCC-3.3 to GCC-3.4 and the ABI changed. Or that time in 2009 where I installed a 0.x version of Pulseaudio on my gaming machine. Or that time I replaced OpenSSL with LibreSSL on my personal computer. If your server takes a shit because somebody was fucking around doing stupid shit on prod, and you do root cause analysis and come up with a reason that it broke other than, "employee was fucking around and doing stupid shit on prod" and the recommendation is something other than "don't fuck around and do stupid shit on prod" I don't know what to tell you. Dynamic linking isn't going to stop a sufficiently determined idiot from bringing down your server. Neither will static linking.
> What do you mean "which versions of which libraries"?
If you upgrade a shared library to fix a problem, how do you know that the application has been tested against the fixed version?
And no, your package manager won't know.
Congratulations on a) not having multiple installs of shared libraries on your system and b) for knowing which version you have. Knowing this isn't very common.
> If you upgrade a shared library to fix a problem, how do you know that the application has been tested against the fixed version?
Distro's like Debian solve that problem by not upgrading. The only things deemed worthy of "fixing" are security issues, and they are fixed by backporting the fix (only) to the existing shared library. Thus no API's (of any sort - even unofficial ones like screen scraping) are upgraded or changed, so no testing is necessary.
And thus:
> And no, your package manager won't know.
It doesn't have to know, because the package manager can assume all releases for Debian stable are backward compatible with all the packages in that release.
A lot of the noise you see on HN comes from people using distro's on their desktops. To them a distro is a collection of pre-packaged software with all the latest shinies, which they upgrade regularly. But Linux's desktop usage is 3%, whereas it server usage is claimed to be over 95% (which eclipses Windows Desktop share). Consequently distros are largely shaped not by the noisy desktop users, but by the requirements of sysadmin's. They need a platform that is guaranteed both stable and secure for years. To keep it stable, they must solve the problem you describe, and for the most part they have.
If you're linking to OpenSSL, it's scary to have that upgraded from under you. Maybe it got better in the 3 series, but I seem to recall pretty much all the important 1.0.1? releases would be something you'd need to mitigate a bit vulnerability, but would also have api changes that would break your application if you were trying to do newish things. Sometimes justified, but still a pita.
Somehow this makes me think of games Back In The Day where you could simply replace your crosshair by editing a bitmap file, versus now where everything's so much more locked-down behind proprietary container formats and baked-in checksums, etc.
Monolithic builds are great if you have no control over the deployed environment (IE desktop apps sans OS supplied libs). They’re worse if you do control the environment and how the upgrade paths get followed
Doesn't it seem that more and more people are just given access to some managed environment they have little control over anyway?
I feel like sometimes the dependency on dynamically linked stuff is akin to "well transistor radios are great if you don't care about soldering on fresh vacuum tubes like a real radio person would."
A dynamically linked library need only have one image of itself in memory.
If you are running a process that, for example, forks 128 of itself, do you want every library it uses to have a separate copy of that library in memory?
That's probably the biggest benefit. But it also speeds up load time if your executable doesn't have to load a huge memory image when it starts up, but can link to an already in-memory image of its library(s).
The only real downside is exporting your executable into another environment where the various dynamic library versions might cause a problem. For that we have Docker these days. Just ship the entire package.
> If you are running a process that, for example, forks 128 of itself, do you want every library it uses to have a separate copy of that library in memory?
> it also speeds up load time if your executable doesn't have to load a huge memory image when it starts up
I'm not sure about Windows and Mac, but Linux uses "demand paging" and only loads the used pages of the executable as needed. It doesn't load the entire executable on startup
You'd love NixOS. Gives you the flexibility of dynamic libraries with the isolation and full dependency bundling per app and less janky than snap or flatpak.
Slight tangent: it bugs me when people say "it goes against the Unix philosophy" as though The Unix Philosophy were some kind of religious text. Not everything should be a pluggable Unix executable, and Fossil making non-Unixy choices doesn't reflect poorly on it. They just chose a different philosophy.
I’m so thankful that Rust is helping popularize the solo exe that “just works”.
I don’t care if a program uses DLLs or not. But my rule is “ship your fucking dependencies”. Python is the worst offender at making it god damned impossible to build and run a fucking program. I swear Docker and friends only exist because merely executing a modern program is so complicated and fragile it requires a full system image.
> I’m so thankful that Rust is helping popularize the solo exe that “just works”.
Wasn't it Go that did that? I mean, not only was Go doing that before Rust, but even currently there's maybe 100 Go-employed developers churning out code for every 1 Rust-employed developer.
Either way “Rust is helping” is true. And given that Go is a managed language it never really factored into the shared library debate to begin with, whereas Rust forces the issue.
Maybe, but it's misleading. Using the assertion that "$FOO made $BAR popular" when $FOO contributed 1% of that effort and $BAZ contributed the other 99% is enough to make most people consider the original statement inaccurate.
> And given that Go is a managed language it never really factored into the shared library debate to begin with, whereas Rust forces the issue.
How so? Rust allows both shared and static compilation, so it's actually the opposite - Rust specifically doesn't force the use of single-binaries.
I'm struggling to interpret what it is you are saying: Go specifically forces the use of static linkage, whereas in Rust it's optional, is it not?
I am under the belief that in Rust you can opt-out of static linkage, while I know that in Go you cannot.
Are you saying that Rust doesn't allow opt-out of static linkage?
> Using the assertion that "$FOO made $BAR popular"
Thankfully that’s not what I said! This sub-thread is very silly.
FWIW Rust is exceptionally bad at dynamic/shared libraries. There’s a kajillion Rust CLI tools and approximately all of them are single file executables. It’s great.
I have lots of experience with Rust, the Rust community, and a smorgasbords of “rewrite it in Rust” tools. I personally have zero experience with Go, it’s community, and afaik Go tools. I’m sure I’ve used something written in Go without realizing it. YMMV.
Ehhh. You can compile a single exe with C or C++. I’ve personally come across far more Rust tools than Go. But I don’t really touch anything web related. YMMV.
The choice is actually between dealing with complexity and shifting responsibility for that to someone else. The tools themselves (e.g. virtual environments) can be used for both. Either people responsible for packaging (authors, distribution maintainers, etc.) have some vague or precise understanding of how their code is used, on which systems, what are its dependencies (not mere names and versions, but functional blocks and their relative importance), when they might not be available, and which releases break which compatibility options, or they say “it builds for me with default settings, everything else is not my problem”.
> Either people responsible for packaging have some vague or precise understanding of how their code is used, on which systems, what are its dependencies
But with python it’s a total mess. I’ve been using automatic1111 lately to generate stable diffusion images. The tool maintains multiple multi-hundred line script files for each OS which try to guess the correct version of all the dependencies to download and install. What a mess! And why is the job of figuring out the right version of pytorch the job of an end user program? I don’t know if PyTorch is uniquely bad at this, but all this work is the job of a package manager with well designed packages.
It should be as easy as “cargo run” to run the program, no matter how many or how few dependencies there are. No matter what operating system I’m using. Even npm does a better job of this than python.
A lot of problem with Python packages is the fact that a lot of Python programs is not just Python. You have a significant amount of C++, Cython, and binaries (like Intel MKL) when it comes to scientific Python and machine learning. All of these tools have different build processes than pip so if you want to ship with them you end up bring the whole barn with you. A lot of these problems was fixed with python wheels, where they pack the binary in the package.
Personally, I haven't ran into a problem with Python packaging recently. I was running https://github.com/zyddnys/manga-image-translator (very cool project btw) and I didn't ran into any issues getting it to work locally on a Windows machine with Nvidia GPU.
Then the author of that script is the one who deals with said complexity in that specific manner, either because of upstream inability to provide releases for every combination of operating system and hardware, or because some people are strictly focused on hard problems in their part of implementation, or something else.
A package manager with “well designed” packages still can't define what they do, invent program logic and behavior. Someone has to choose just the same, and can make good or bad decisions. For example, nothing prohibits a calculator application that depends on a full compile and build system for certain language (in run-time), or on Electron framework. In fact, it's totally possible to have such example programs. However, we can't automatically deduce whether packaging that for a different system is going to be problematic, and which are better alternatives.
> A package manager with “well designed” packages still can't define what they do, invent program logic and behavior.
The solution to this is easy and widespread. Just ship scripts with the package which allow it to compile and configure itself for the host system. Apt, npm, homebrew and cargo all allow packages to do this when necessary.
A well designed PyTorch package (in a well designed package manager) could contain a stub that, when installed, looks at the host system and select and locally installs the correct version of the PyTorch binary based on its environment and configuration.
This should be the job of the PyTorch package. Not the job of every single downstream consumer of PyTorch to handle independently.
> Just ship scripts with the package which allow it to compile and configure itself for the host system.
Eek. That sounds awful to me. it is exceptionally complex, fragile, and error prone. The easy solution is to SHIP YOUR FUCKING DEPENDENCIES.
I’m a Windows man. Which means I don’t really use an OS level packages manager. What I expect is a zip file that I can extract and double-click an exe. To be clear I’m talking about running a program as an end user.
Compiling and packaging a program is a different and intrinsically more complex story. That said, I 1000% believe that build systems should exclusively use toolchains that are part of the monorepo. Build systems should never use any system installed tools. This is more complex to setup, but quite delightful and reliable once you have it.
I remember having to modify one of those dependency scripts to get it running at all on my laptop.
In the end I had more luck with Easy Diffusion. Not sure why, but it also generated better images with the same models out of the box.
The only way I know to manage python dependencies is Bazel as the build system, and implementing a custom set of rules that download and build all python dependencies. The download is done in a git repo. All magically missing libs must be added to the repo and Bazel. And finally you might have a way to... tar the output into a docker container... sigh
> it goes against the Unix philosophy of do one thing and do it well
For me, Perl shows just how restricted that viewpoint was.
After I learned Perl, I stopped caring about tr, and sed, and many of the other "one thing well" command-line tools. And I've no desire to swap out and modify the 's//' component of perl.
Perl does "one thing" - interpret Perl programs - even though it also replaces many things.
I know 'rmdir' exists. It does one thing, well - remove an empty directory. It's been around since the first release of Unix.
However, I use "rm -rf" because it's easier to use a more powerful tool which handles empty directory removal as a special case.
You can also change your viewpoint and say that Fossil does do one thing well: it's a distributed project control system. That's a new category I just made up, to highlight just how subjective "one thing" is.
I like `rmdir` because I don't have to check if a directory that I think is empty is actually empty with `ls -la` before removing it. This happens a lot with moving stuff out of directories (sometimes to different destinations).
% man cc
...
DESCRIPTION
clang is a C, C++, and Objective-C compiler which encompasses
preprocessing, parsing, optimization, code generation, assembly, and
linking.
% man gcc
...
NAME
gcc - GNU project C and C++ compiler
...
> To me it's obviously cleaner to divide a system into components that can later be swapped or modified independently.
But where do you draw the line? What's "one thing"? - The size and complexity between cli tools doing one thing varies by orders of magnitude, some of those programs are much larger than this Fossil "monolith". Should a component have more functionality if separation means 10 times slower performance? What if it has hundreds of such features? What if separating those features means a hundredfold increase in complexity for setting up the software as it now has distributed dependencies? Should you have a separate audio player when a video player could already do the job out of necessity? Should a terminal support scrolling if you can already get that via tmux?
The Unix philosophy is bad for judging individual programs.
Unix’s philosophy is more of what you’d call ‘guidelines’, and is not universally applicable — not all problems can be decomposed nicely, and IPC just gives you a badly debuggable hodgepodge of added accidental complexity. It’s good for trivial tools like ls, cat, etc, but something more complex is likely better off as a monolith.
> As you mentioned it goes against the Unix philosophy of do one thing and do it well. To me it's obviously cleaner to divide a system into components that can later be swapped or modified independently.
Anecdote: when i first met Richard in 2011, after having contributed to Fossil since 2008, i asked him why he chose to implement fossil as a monolithic app instead of as a library. His answer was, "because I wanted it working next week instead of next month." It was a matter of expedience and rewriting it now would be a major undertaking for little benefit.
Reimplementing fossil as a library is a years-long undertaking (literally) and is not something we're interested in doing directly within the Fossil project, but is something i maintain as a semi-third-party effort, along with a handful of other Fossil contributors, over at <https://fossil.wanderinghorse.net/r/libfossil>.
> Imagine editing a spreadsheet like `cat foo.xls | select-cell B3 | replace '=B2+1' > foo.xls`.
It would be even more cumbersome than that. After that command you'd have to restore foo.xls from a backup, and then do the edit again this time remembering that the "> foo.xls" executes before the pipe executes. :-)
I wonder if anyone has written something to make pipes like that work? E.g., write two programs, "replace" and "with" that could be used like this:
replace foo.xls | ... | with foo.xls
What "replace [file]" would do is set a write lock on the file, copy the file to stdout, then release the lock.
What "with [file]" would do is copy stdin to the file, after obtaining a write lock on the file. I think most shells would start the components of a pipe in order so "replace" should be able to set its lock before "with" tries to get a lock, but to be safe "with" could be written to buffer incoming data and only start checking the lock after it has received a significant amount or seen an EOF on stdin. Or "replace" and "with" could coordinate using some out-of-band method.
I think the "Unix philosophy" is best applied to problems that indeed can be de-composed into clear discrete steps. In fact, that's the metric I use when I write command line utilities: does this make sense in a pipe?
There are a lot of things where this isn't very practical. For instance, imagine building a web server that consists of a couple of dozen discrete utilities that are then cobbled together using pipes. Or even implementing the core feature set of Git in this manner. Would it be practical? Would it be better if Git was an enormous shellscript that connected all of these "things" into an application? What does that give you? And what would be the cost?
How would you do SQLite (the CLI application) as a bunch of discrete commands?
The UNIX philosophy of minimal cmdline tools that do one thing right is fine and the Go-style 'monolithic exe' without runtime dependencies except the OS is also fine (and both philosophies actually don't need to collide).
The problem is all the software that depends on tons of dependencies that are brought in dynamically. Just look at Jekyll vs Hugo. I have Jekyll break regularly when something (seemingly) unrelated changes on my machine, but Hugo is just rock solid.
Or another much more annoying example: Linux executables linking with glibc and then not running on systems that don't have that particular version of glibc installed.
> To me it's obviously cleaner to divide a system into components that can later be swapped or modified independently.
Why is "cleaner" the only thing that matters? Why not "functional/featureful"? It's open source so it can be modified, but I'm not sure why ability to swap matters.
Exceptional things rarely happen without some outlier conviction involved. Most things happening due to outlier convictions are just that, follies that lead nowhere. But when the stars align and there's both great ability involved and a genuine gap to fill that would have remained undiscovered workout the outlier conviction, something like SQLite happens.
> git, for all its issues, is not bundling the kitchen sink.
It doesn't bundle the kitchen sink in its native *nix environment, but for Windows it does. Git installer is > 50 MB, including (if I remember correctly) even a terminal.
While you can download Fossil as a 3.3 MB standalone binary for any supported platform.
Let's not forget how long it even took for there to be a reasonable Windows build of git. Git implicitly relied on significant amounts of Linux tooling which required bringing over an entire Mingw environment.
Actually I do to save me from the deprived interfaces the OS ships with.
The Git install is one of the best Cygwin-likes I've encountered. It has the majority of tools needed and reasonable integration with the host OS. Very nice for getting something done quickly on any random Windows box.
It's fine if you don't have anything else installed already, but I have MSYS2 installed so it'd be nice if it were optional. Realistically an extra 50mb is not going to materially affect my life, but it's still aesthetically displeasing.
I agree - that's why I use the git package in MSYS2, which afaik is just as capable (and makes it much easier to use git with the full array of UNIX tools I might want to use that don't necessarily ship with Git for Windows).
I remember people installing git-bash and putty for Windows in computer science class to fill in all the gaps. Idk what the deal was with that cause, uh, why would I use Windows.
Actually it does, because with the windows git it includes it's own copy of ssh and bash, both of which will clash and fight with msys and/or other ssh installs - including the copy of ssh that microsoft themselves tuck away in \windows\system32
it's quite 'normal' for git-for-windows' ssh-agent to completely disable ssh-agent from working properly system-wide because it ends up pointing things at the wrong ssh-agent.
Pretty much all game development still happens on Windows because that's where all (or at least most of) the gamedev tools and middleware libraries are.
That's a pretty ignorant view, there's tons of developers using Windows. If you take a look at the SO survey (or similar ones), Windows has 47% in the "Professional use" category.
And yet, because git does not bundle those things, which actually do belong as part of a modern SCMS, people lock themselves into GitHub or Gitlab, which provide those missing pieces.
Git includes a web interface written as a perl CGI script, so yeah it has a lot more dependencies than people realize. It is most certainly not just a simple single binary to plop on a machine and call it good.
> I do prefer the "do one thing and do it well" approach.
I prefer the "do what you do well" approach. If it's one thing, or many things, doesn't matter, as long as it's both efficient and correct.
I mean, if Fossil fails at some of these things, then we can criticise it for its failings, but it appears it actually does the things correctly.
The comparison with GitLab is quite enlightening. Fossil is a few MB, and Git + GitLab (to be feature equivalent) is a few GB and requires far more resources. Then which one does what it does well?
Now, there are a few things I don't like from Fossil, like the lack of a cherry-pick command. I have no intention of using Fossil over Git. I am just stating that criticism should be based on actual misfeatures and not on development "philosophies".
Earlier in it's history, Fossil didn't have a separate cherry-pick command, but rather just a --cherrypick option to the "merge" command. See https://fossil-scm.org/home/help?cmd=merge. Perhaps that is where you got the idea that Fossil did not cherry-pick.
Fossil has always been able to cherry-pick. Furthermore, Fossil actually keeps track of cherry-picks. Git does not - there is no space in the Git file format to track cherry-picks merges. As a result, Fossil is able to show cherry-picks on the timeline graph. It shows cherry-pick merges as dashed lines, as opposed to solid lines for regular merges. For example the "branch-3.42" branch (https://sqlite.org/src/timeline?r=branch-3.42) consists of nothing but cherry-picks of bug fixes that have been checked into trunk since the 3.42.0 release.
I think the point is that there is the option to have only git, which reduces the attack surface of only that tool, if you don't want/need anything else.
Why do you think it is a strength that git is "not bundling the kitchen sink"? I'd like to understand better why other people prefer kitchen sink vs multiple binaries.
I am in two minds when it comes to this. A lot of (server) software I write bundles server, client and tools in the same binary. I also embed the API documentation, the OpenAPI files, the documentation and sometimes related documentation in the binary so that it can be served on an endpoint on the server or extracted.
So you have one binary, statically linked whenever possible, that contains everything you will need. And where everything is the same release as everything else, so there are no chances you'll end up with different versions of client, server, documentation, tooling etc.
The binary size doesn't concern me. I could easily increase the binary size tenfold, and it still wouldn't be a problem for the software I write. I don't think binary size is a big concern today since so much software "splats" files all over your system anyway (which I think is a horrific way to do things), so footprints tend to be somewhat large anyway.
What occasionally does concern me is that this might be confusing to the user. But it is possible to make things confusing for the user even if a piece of software is more focused (ie does "one thing"). One example is CLI utilities that have multiple screenfuls of `--help` output. To me, that's poor usability. Users end up resizing terminal windows, scrolling back and forth (when you deal with related options) and perhaps even resorting to grep or less to find what you are looking for.
I try to mitigate this by always structuring CLI applications with commands and subcommands. Where you can do --help at each level. Quite a few CLI applications do this and I think it helps.
This summer I wrote the first piece of software in perhaps half a decade that has separate binaries for the client and the server. Because I want to share the client code, but not the server code. While the split was unrelated to usability, I've started asking myself if this presents a better user experience. I haven't really been able to conclude.
Ok that’s not fair. Git is pretty okay for the Linux open source project. But it’s pretty mediocre-to-bad for everything else.
The D is DVCS is a waste of effort. Almost all projects are defacto centralized. In fact the D is anti-pattern that makes things like large binary files a still unsolved problem in Git. And no Git LFS doesn’t count.
Source control should be capable for petabyte scale storage and terabyte scale partial clones, imho.
Git feels like an inferior technology that succeeded and now we’re mostly stuck with it. Maybe someday someone will create a proper Perforce competitor and we can all migrate to something that’s actually good.
Counterpoint: Lots of people actually use and like the D aspect. It’s one of the best things about Git!
Local git repos can be shallow or partial clones if you insist on it. You say elsewhere that a VCS should support an offline mode instead, but if that’s not a copy of the repository, how is it in any way equivalent and what exactly is the difference?
I’ve never understood why people like Perforce; I’ve assumed it’s some kind of weird nostalgia for mainframe user interfaces. I understand that it handles some kinds of large assets better than Git, but Perforce is so bad at everything else.
People don’t necessarily “like” Perforce. However it is functional for professional game projects, and other systems like Git and Mercurial are not. Perforce is ripe for disruption.
> if that’s not a copy of the repository, how is it in any way equivalent and what exactly is the difference?
“Distributed” implies the user machine is at least capable of downloading the full repo history. Git defaults to full clones and has various shallow clone features. It also implies support for extremely convoluted graphs and edge cases.
Offline implies a single central hub you connect to and sync with at some later point. I expect the only use case for downloading full history to be for backup purposes. Almost all operations can be performed without having access to every version of every file.
I like perforce. It scales significantly better than git, (running git status on a large project, or cloning one takes significantly longer via git than p4). Not having the entire history of a project locally on disk is a pro to me, not a con. P4merge is orders of magnitude better than git's. Atomically incrementing numbers for changelists are superior to sha's if the first thing you do is implement version numbers on top of git. The default workflow is sane and teachable in all of 10 minutes even to non technical people (designers, artists). I like that history is immutable - there are admin tools available if surgery is needed.
P4 isnt perfect, but it's definitely got significant advantages over git in many areas.
Or on a plane. It’s nice to have 100% of its functionality when you have 0% of your usual connectivity. Branches, commits, merges, all from the local file system? Yes, please.
There’s a reason we moved off centralized VCS en masse.
> Or on a plane. It’s nice to have 100% of its functionality when you have 0% of your usual connectivity. Branches, commits, merges, all from the local file system? Yes, please.
You don't need the VCS to be a distributed VCS to have offline capability.
> There’s a reason we moved off centralized VCS en masse.
No, there's a reason we moved to git specifically. We didn't move to the competing DVCS, did we?
Sorry, but you’re completely and objectively wrong. This is a huge misnomer.
Distributed and “offline support” are fully orthogonal features.
Distributed means every user has a full copy of the entire repo including full history. This is a radical and unnecessary limitation on the scope and size of source control.
You can have full support for branching, commits, and merges without a fully distributed repo. There are numerous examples of this.
That's an interesting, and wrong, definition of "wrong".
Git, Mercurial, and the like make every full copy of the repo equal. By convention, we often use central repos like GitHub, and commands like "git fetch" and "git push" as fast ways to sync their contents. We don't have to, though.
I can clone a remote repo, then work independently for months. I do this all the time with the Mastodon server I run. I periodically pull in upstream changes, merge them into my working copy, then push those changes out to my worker instances. I might SSH into one of those servers, fix something specific to it, push the changes out to the other local servers so that they're all synced, and repeat for weeks and months on end.
And because each of those repos are equally "official", all branching and merging operations are equally easy on each one of the peer machines. Although it's conceptually possible that it could be just as easy on a VCS that doesn't work with full clones, I've never seen it.
It seems you're still largely talking about mostly text files. The parent you're replying to works in video games, where 99% of the data stored in VCS by volume (if it's even stored in VCS) is not text data. It is things like textures, audio files, processed geometry..etc. It is extremely easy to have one single texture take up more disk space than the entire source code for the game.
> I can clone a remote repo, then work independently for months.
If you're working with more than 0 other people in video games, good frakking luck doing this. If you're working on a large enough game, you're also going to need potentially multiple TB of storage just to have a full shallow copy of the repo (with just the latest copies.) I have worked at a studio where a full deep clone of the repo for just one game was well over 100TB. Let's see you load that up on your laptop.
The don’t use Git for it. Emacs is a crappy Photoshop replacement, but it’s great at it was actually built for. Git isn’t great for video game assets, but it’s great at what it was actually built for.
Use the right tool for the job. The parent poster is complaining that their employer picked the wrong tool for their job, then insisting that the tool sucks.
Git is optimized for a specific use case. This prohibits other use cases. I think Git could be slightly tweaked to optimize for and enable different use cases. I think far more users would benefit from the new use cases than the old.
I want to use the right tool for the job. I wish Git were changed slightly so that it could be the right tool.
Git is not capable of handling video game assets. It could be. I wish it were. You may may be happy as is. I think you would actually be happier if my use case were supported. Because I think Git is over optimized for an ultra niche case that doesn’t matter to most users. And yes I realize most users are not game developers.
Git is great at what it was built for. Almost all current Git users do have the same requirements as the thing Git was built for. Therefore Git is a sub-optimal tool for almost all users. The world deserves an optimal tool. The hegemony of Git and GitHub makes it difficult for an optimal tool to be made and therefore all users suffer.
Interesting usecase. The "git bad for everything else" commenter was probably unaware of it.
That said, it's not very representative of what git is mostly used for and where there comparison with fossil is least favorable.
> Distributed means every user has a full copy of the entire repo including full history.
Then git must not be a DVCS; I use shallow clones all the time.
In any event, centralized systems probably can do offline support, at least in theory, but DVCSs more or less include it for free by default, which is still worth something.
Local history doesn’t imply D. The D basically means that clients and servers are equivalent. You could have a centralized VCS with client-server asymmetry and still have local history.
I was once responsible for doing this with a Perforce server. Only time in my career a VCS has lost data. This was decades ago now and the data loss might have been due to hardware; I cannot definitively blame Perforce, but man was it shitty to deal with at the time. We migrated to Subversion and never had another issue.
Git is a “distributed version control system” (DVCS). You’re just adding the term “source code” for no particular reason.
I make video games. Video games contain far more data than mere source code. Almost all game devs use Perforce because Git is insufficient.
Artists and designers desperately need more version control in their lives. They are mostly absent because their programmers use Git which is insufficient. Its a god damn shame how much of our businesses use “stuff_final_final_05.psd” for “version control”.
Amen. I also work[ed] in video games, and this rings very true to me. Git worked well enough for the programmers, but when you're dealing with artists, producers, designers, writers, audio engineers all needing to share work on assets that are also tied to specific versions of source, Git falls apart.
One studio I was at actually had a custom VCS that was a combination of SVN + homebrew asset versioning that worked decently well. By that I mean we all hated the shit out of having to use it, but it worked better than most anything we could get our hands on at the time for a reasonable price.
I think Git is a very clunky rock that results in people smashing their fingers and is custom designed for a very specific use case (Linux open source) that isn’t actually relevant to 99.99% of projects.
I think Git is a local minimum that people are ignorantly satisfied with. Everyone is using a mishappen rock and the popularity of this rock is inhibiting the creation of a proper hammer.
I could be wrong! But I am unfortunately forced to used Git due to its ubiquity even though it’s an extremely limited tool. Git does not spark my joy.
Mercurial is very similar to Git but incrementally better. In a different world we’d all use MercurialHub. I wouldn’t be fully
happy with Mercurial either. But the point is that Git’s ubiquity has to do with ecosystem factors beyond its intrinsic capabilities and design.
Git is a mediocre hammer, at absolute best. I want a great hammer. Users incorrectly think Git is a great hammer which is making it difficult for an actually great hammer to be built.
Almost all HN users will disagree with me. They’re quite happy with Git and think it’s a great hammer. I think they’re all wrong. But maybe it is me who is wrong! :)
It's been quite a while since I used other version control systems (such as Mercurial) to any greater extent, so I'll have to rely on my recollection of the feelings and thoughts I had when I did. I also don't really know what the current state of Mercurial is.
My impression of Git in relation to e.g. Mercurial was that Git was harder to get into. Once I did become comfortable and began to kind of understand how git works, though, it seemed to make it possible to do just about anything I wanted to do with source code. In particular, branches, merging, cherry-picking etc. work well and are fast. Doing local experiments before settling for a solution, rebasing your work on latest (already shared) other developments before publishing it to others, etc. are well enabled by those features.
Limited is not how I would describe Git. In fact, it seems rather versatile, as far as managing source code or other similar line-oriented text-based formats go. Grokking it well enough to use that versatility isn't easy, and some of the terminology it uses is just confusing, but once I got past that, it seems to enable lots of workflows that are useful for actual work on source code.
What it of course probably doesn't do that well is handling large blobs. Most software projects don't actually have lots of those, and when there are some, they're often somewhat static. So for most developers, that's usually not a major limitation of the tool. But it almost certainly is to you.
Another thing, of course, is that it's basically just a tool for keeping track of and managing versions and contents of text files. It's not, by itself, a tool for managing higher-level workflows of an entire development project, or for really handling specific formats, or anything else higher level that's not somehow related to managing source code or something similar. That can also be a major limitation. But I don't think that makes it a poor tool; in lots of programming, keeping track of and managing versions and contents of source code in multiple branches is the central use case. Tools for code reviews and other higher level project workflows can then be built separately on top of that.
When you say it's a mediocre hammer, I think you and other people just have different ideas of what a hammer is and what they typically need out of it.
Mercurial probably also allows for all of those things that lots of people like Git for. I honestly don't quite remember what the differences were or how I felt about them when I used both, except that Mercurial seemed easier to handle at first but Git felt possibly more versatile once I got used to it. I can't quite remember what gave me the latter feeling but it's quite possible the choice really made little difference in the end.
For what it's worth, I think BitBucket used to support Mercurial, so we did kind of have something along the lines of GitHub (at the time) for Mercurial.
To continue along the "mediocre hammer" line, is there something specific about Git that makes it seem only mediocre to you if you considered a hammer to be a tool for handling source code alone? How is it limited in that regard?
The world has non-text files that require version control support. Version control systems are mostly bad-to-terrible for anything other than source code. Implying that the use case is wrong is borderline offensive.
It’d be nice if there were some artist/designer friendly version control systems. I can teach someone who has never even heard of version control how to use Perforce in 10 minutes. It’s darn near idiot proof and near impossible to shoot your foot off. Git is not easy to use. This is evidenced by the tens of thousands of blogs explaining how easy and simple to use it is. If that were the case there wouldn’t be need for all those posts!
> The world has non-text files that require version control support
Which is fine, but saying that git is rubbish because it doesn't handle binary files as you want it to is a bad usecase.
How version control would handle diffs between PDFs is not the same as photos, which is not the same as video. They have to be content aware for these sorts of things.
Well, to be frank, git doesn't really handle binary files _at all_. I don't really consider treating binary files as opaque blobs of data as 'handling them'. It's more akin to throwing your hands up and saying 'fuck it, we'll treat it like the text stuff and whatever happens, happens.' Yes, over time git has gained some capability for handling binary data as delta patches, but it is so far away from anything even remotely resembling content-awareness.
How would we represent video diffs? I don't deal with video so I'm not an expert, but there appears to be people complaining without suggesting solutions.
Not all version controlled files can be merged. That’s fine. Git sucks at working with large binary files. Perforce does not. Therefore all game devs use Perforce.
A theoretical Git2 could provide Perforce-tier support for large binary files. But, imho, this would likely require dropping the D in DVCS. I would gladly trade distributed for large binary file support. Without even a moment’s hesitation. Other people wouldn’t. But I wouldn’t call their use case “bad”.
Git is rubbish for my needs. It’s rubbish for a lot of needs. It’s ok at some things. Mercurial is much better at those things though.
Text is a universally understood file format. That means it can be easily diffed, compressed, smartly stored (like storing only changes). That's not true of binaries, at least most of them. That's why I'm pessimistic about a good universal VCS ever existing.
I would also love some kind of good (even decent would be enough) VCS for binary/non-text files. I get a stress rash just watching our designers work with "final_final_2023_1_backup_new.psd".
I think Git is relatively simple in relation to all the complicated things you can do with it. If you don't need/use those complicated things, it of course feels like way too much work for too little pay off.
Ah, this is why you have a bad attitude about the “D” part of “DVCS”, right? The workflow for art is “I need to lock that graphics asset so that no one else edits it while I’m editing it,” which you can’t do with a DVCS. Disallowing exclusive edits is generally what most programming teams want; otherwise it’s a daily occurrence to try to get someone to unlock a file they locked for editing and forgot about.
Not really. Locking of binary assets is a separate topic I’ve ignored.
I don’t actually like or dislike the “distributed” part. I don’t care about it. At all. In the slightest. Almost all projects are defacto centralized. If decentralization was free then great, more features for free.
My experience is that distributed is not free. It appears to me to be a fatal flaw that prevents Git from ever being a good tool for large projects with large binary assets, such as games. So I would sacrifice it in a heartbeat IF it gave me the features I do care about.
Locking is just punting on the problem. If a version control system can't merge non-conflicting changes to the same file by different people, that file is unmaintainable and shouldn't have been checked in as if it were source code. Instead it should be generated from a set of files that can be edited normally.
There are features which make life a lot better when you have them: A local search to explore, a way to stash the working state to try something out etc. and once you got those you have mostly a distributed VCS. True the flexibility of multiple remotes and tracking branches most users probably don't need, but it's quite nice for various things, and be it only a simple backup way.
On an aside: I always chuckle on the "distributed" VCS. Back in the days some people refered to CVS as a distributed VCS, comparing to RCS.
You might appreciate then how fossil improves on git. When that happens with fossil you can also still update the issue tracker and wiki, while many (most?) people depends on a centralized system like GitHub or GitLab for the latter.
One thing that I have observed about programmers is how obsessed they are with tooling. Whether it’s exactly which model of ergonomic keyboard or exactly which toolchain(s) they’re using, there seems to be an endless desire or eagerness to shoot the shit over tooling.
> git-erase-working-treeshould be used when you want to cautiously erase the current working tree of an upstream root and the config, and want to quiltimport to a active GUI.
I'm sure there are others, but the fact that the same document can be found through various paths (without www domain, without /drafts/ path, or without /matrix/ path) makes it harder to find previous postings.
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.
I saw this video few days ago which describes some of the alternative to Git and of course Fossil is one of them. I have used Fossil in some projects and found to be ok.
I found Pijul https://pijul.org/ described in this talk to be very interesting. It was discussed on HN before.
Source:
https://www.youtube.com/watch?v=M4KktA_jbOE
I’ve used jj on a couple of small personal projects and it was fine, but I needed to get my head out of “git mode”. The lead developer is very helpful.
Pijul has always fascinated me. It’s like the holy grail of version control. But for my personal projects, I develop in a straight line anyway, and I’m not in control of what’s used at work, so I’ve never really used it.
Check out https://github.com/martinvonz/jj/. It's highly inspired by Pijul, among VCSes, and uses a git backing store, so you can use it personally and (mostly) seamlessly interact with any git-only team.
Pijul will be ready when it support the ability to email patches as a universal fallback method of submitting patches upstream for those that do not wish to create an account with a given service.
Isn't the patch/diff format already universal? I mean the one you generate with diff [0] and apply with patch [1]. You don't need the vcs to generate it.
There’s some metadata that is lost unless the user explicitly provides it (username/email might not be the ones sent with the email & that could be an error or for security/privacy reasons). The tool can provide a format that makes it easier to record & handle conflicts as well as streamlining the process to get it to email. You’re not wrong tho that patch/diff can be good/enough for a lot of use cases.
I've used Fossil for a private local project. It's quite a capable revision control system with a very decent web UI. Just a word of warning - make frequent backups of the backing sqlite repository database. I had upgraded fossil to make a few commits and then I inadvertently made a commit using an older version of fossil and it corrupted the fossil repo database irreparably and a few days' of work was lost. I've never had GIT corrupt a repo in ten years of daily use - regardless of version.
As a counterpoint, I've been completely unreasonable with my use of fossil. Wildly different versions on different systems, often from years apart. They get whatever binary existed when I set up the system and stay on it. Some osx, some variations of Linux, a freebsd box. I think windows if I go back far enough. Synchronising between them in ad hoc fashion.
Some repos are over a decade old. One is over 10k commits deep, another several gigabytes in size because I checked in whole dev environments.
Every now and again it told me it wanted to rebuild and that succeeded. I routinely ctrl-c it partway through a commit if I notice a typo.
It has _never_ dropped the ball on me. Fossil is by a wide margin the most reliable program I've ever used.
I dispute this claim. The underlying artifact format for Fossil is compatible
back to the beginning. There have been enhancements, but nothing that would break. And there have been no reports of breakage among the countless users on the Fossil Forum.
I suspect what the OP encountered was that he checked in some things using a newer version of Fossil that had enhanced capabilities. (For example, Fossil originally only use SHA1 hashes, but was enhanced to support both SHA1 or SHA3 after the SHAttered attack.) Then the OP tried to extract using an older Fossil that didn't understand the new feature and returned an error. I'm guessing at this, of course, but that seems like the most likely scenario.
I have never once made a backup of SQLite repo or the Fossil self-hosting repo, or any of the other 100+ Fossil repositories that I have at hand. I've cloned the repos to other machines as disaster protection. In fact, I have cron jobs running on machines all over the world that "sync" critical Fossil repositories (such as SQLite) once an hour or so. But I have never even once made a pure backup.
I did have the primary SQLite repo go corrupt on my once, years ago. Somehow, file descriptor 2 got closed. Then when the SQLite database that is the repository was opened, it opened on file descriptor 2. Then some bug in Fossil caused an assert() to fire which wrote on file descriptor 2, overwriting part of the database. I restored the repo from a clone, fixed the assertion fault in Fossil, and enhanced SQLite so that it refuses to use a file descriptor less than 3.
It is yes, they've even built a command for it "rebuild"[0]
> Reconstruct the named repository database from the core records. Run this command after updating the fossil executable in a way that changes the database schema.
Afaik fossil just uses sqlite under the hood to store metadata. It would surprise me sqlite doesnt stash min and max required versions and refuse to work outside of those bounds
It does do exactly that. If you visit https://sqlite.org/src/stat, the "Schema Version" line tells you exactly what version of the database schema that the repository is using. The SQLite repository uses the very latest Fossil schema, which you can see from the "stat" page has not changed in 8.5 years.
Builtin UI looks OK. (Usable and easy to navigate actually). But I was hoping the UI support commit as well. (I could not figure this out in UI). (so you don't have to mix command line and web interface to get things done)
I think if we can build a wrapper UI around fossil (which allows open, init, commit, sync?, sync-with-git, start-web-interface) (or even better add it to fossil itself).
Then, this would be highly helpful to less-techy or non-devs that code (bio, math, data-science, etc) to maintain Jupyter notebooks,etc. Hmm, but perhaps a simple git-ui client can be used for that as well. (but you will loose the builtin wiki/tickets). And ability to work locally is useful as well (but then git can do that too). In any case I have seen less-techy people shy away from git (or version control in general).
I can see the potential in builtin wiki and tickets in same repo. One file to backup is also interesting.
IMHO, for software developers, a version management system is a tool, just like an IDE, or the underlying OS. The less they need to fiddle with these tools, the more productive they are.
Having worked with multiple version management systems, for me, Fossil hits the perfect sweet spot. You literally just set it up and forget about it.
I’m sure git is less than ideal. I pretty much just know enough to do what I need to do with it. The only reason I want to use it is because it is the industry standard tool.
Otherwise Hg, Perforce, have all had pretty compelling arguments put forward for their use.
There’s so much technical churn in this industry, that any time I can use something that’s widely embraced I’m actually happy for that. Regardless of my personal feelings on it.
I use git primarily, but if you work on a project that needs to version control data (images, textures, meshes, sky boxes, terrain, etc.), git, even with LFS, is such a terrible experience compared to Perforce.
>Git focuses on individual branches, because that is exactly what you want for a highly-distributed bazaar-style project such as Linux. Linus Torvalds does not want to see every check-in by every contributor to Linux: such extreme visibility does not scale well. Contrast Fossil, which was written for the cathedral-style SQLite project and its handful of active committers
Ugh...so after all that fanfare of how amazing fossil is, the author admits it just doesn't scale well. I was wondering how that "see it all" approach worked for a busy repo, and now I know, it just doesn't.
I love SQLite, and glad the primary author is happy working on it with fossil. I think if he published it's largest downfall first, it might gain more adoption to folks that could actually use that feature.
Personally I see "doesn't scale well" as a feature, if I'm evaluating something to use on a personal or small project. Tools with clear limits on what they're not for usually have a more polished experience for what they are for.
In that case you might really love "...SCons, a popular Python-based build tool. In a nutshell, my experiments showed that SCons exhibits roughly quadratic growth in build runtimes as the number of targets increases" [0]
I think [0] indicates that it does scale quite well, you can even test by comparing the 2. You can go from cloning to pushing on a repo in half the time. There's branches as well, so while the /timeline[1] seems too busy, you can always drop back to a forum or the bug tracker, which it has already.
time fossil clone https://fossil-scm.org/
time git clone https://github.com/drhsqlite/fossil-mirror
My results were
fossil
time > real 5m43.120s user 2m56.532s sys 0m48.246s
ls -lh > 60M fossil-scm.fossil
git
time > real 10m35.043s user 5m58.427s sys 1m10.555s
du -sh fossil-mirror/.git/ > 829M
It's also significantly faster to clone after the repack:
time git clone --mirror https://github.com/drhsqlite/fossil-mirror
65.10s user 21.22s system 35% cpu 4:05.92 total
time git clone --no-local fossil-mirror fossil-no-repack
26.92s user 2.99s system 155% cpu 19.190 total
git -C fossil-mirror.git repack -a -f -d
time git clone --no-local fossil-mirror fossil-repack
5.42s user 1.18s system 211% cpu 3.121 total
Edit: took new measurements with --mirror on the first clone so that the "local" clones actually get all the branches.
I imagine fossils internal git export function is not robust. Even when you {fossil git export} the repo, you still get a much bigger .git than fossil (20mb more), with errors on some checkouts. Repacking doesn't do much either in this case, so the functionality changes.
Plenty of tech companies have massive monorepos which large numbers of people contribute to. I don’t know how easy it is for one person to see another’s branch though. So: maybe it can scale, at least somewhat, with a more centralised system.
I have a love hate relationship with Git. It is current used for a lot of purposes it was never designed for by Torvald. It is time for something better, unfortunately Fossil isn't likely going to be a Git successor.
I read this years ago, and it really showed me the light. I've used fossil and run it on my own server and it is a dream to work with. I hate working with git, but I do it reluctantly. I'd rather use fossil any day.
I as well, my only gripes with it is there is no firefox persona or some sort of oauth, one of which anybody could contribute to the project without having to sign up. That way everything would be distributed and also easy to contribute and use.
Most of these arguments are nonsense. "Standing up a git server is non-trivial." It's literally just "git init" and providing ssh access to the directory. Most of the other ones seem to suggest the author never learned git.
git has a beautiful data model and a horrible user-space to poke at it. Writing a new user-space makes sense. This seems to poorly re-invent the data model, by virtue of not bothering to understand git.
The only argument I buy is: "2.6. Git provides a poor user experience," and the xkcd is not an exaggeration.
No. It's not. Set up git-shell instead of bash, and you're done. It's literally a one-liner.
There are similar one-liners for most other use-cases.
As a footnote, most environments I'm in, this is a non-issue since devs have ssh access to a common server somewhere. Once you get to the org size where this matters, it doesn't matter since you need Infrastructure with a capital I regardless.
Says the person who clearly has never been the sysadmin for said web server.
Dealing with SSH on a significantly multi-user system is anything but trivial. In more ways than one, this exact problem more than anything else is what spurred the invention of what we now call containers, and it still is not a perfect solution.
Right, and a lot of tools out there already provide a less horrible Git experience by taking care of all the user-hostile command-line arguments (SmartGit, etc).
The only problem with Git is that it is not user-friendly - and that is the Porcelain, the nice API version.
It is non-trivial to stand up a redundent, highly-available, and scalable git server. And if you throw in "with a good web interface", even moreso. But I doubt that is trivial to do with fossil either.
What do you mean by redundant, highly available? Under what circumstances are those necessary? Whatever it is, seems completely orthogonal to version control software. Anyways, I can serve a fossil repo with a great web UI and a few 9s of reliability on an existing web server with literally a 2-line CGI script.
I think at some point, you missed the point of a DVCS.
Scalable?
When do you run into issues with git server scalability that an 80486 couldn't handle?
Highly-available?
At this point, just pay for !@#$ github. But it's a heck of a lot easier to do this in a DVCS than in fossil. Options:
- Set up two servers. Add a hook to push from one to the other whenever a change happens. If the main server goes down, swap to the backup, and bring up a new one as a backup.
- Store the git repo on a redundant, highly-available, scalable file system, and run a few git servers on the shared file system. Back in my day, we'd use AFS for this.
The nice thing about the data model is these solutions /work/. The basic git data model* won't be corrupted if multiple systems are writing to it more-or-less simultaneously. Absolute worst case is the tree splits and you've got a detached head somewhere, but no data is lost.
* I can't speak for some of the more advanced stuff (packing, compression, etc.), since I don't fully understand it; but it's possible to disable all of that.
Spent many years on Subversion and Mercurial before moving to Git.
I agree that it may be complex if you don't take the time to understand the fundamentals.
I made the mistake to jump right at it on a very large project thinking my experience with other non distributed systems would be enough.
So I had to take a step back and dedicate some time to read documentation including visual examples of the most common situations I encounter.
Merging and resolving conflicts are those of two situations where I struggled the most particularly when working with sub branches in large projects (5+ developers) with a very fast pace of development.
Once you understand the fundamentals (you can confidently draw on paper the current and future state of the tree after your changes) Git is not difficult IMO and 99% of the time you can work with a dozen of commands if you have discipline to use standards and do frequent housekeeping.
If you let changes and branches go for two long without committing, merging and deleting them, never tag and release, write poor commit messages and don't reference issue numbers, lack naming conventions, submit dirty PRs and let PRs sit for days and weeks before approval, etc, then the problem isn't Git.
I think the explanation does not make any sense in 2023, if 99.99% of dev use Git you have to use Git, using your own solution that no one else uses or know or need to know is bad.
If you want to make your project more open to contribution you have to use what the rest of the industry is using.
Edit: After reading some responses, I'm really surprised that sqlite does not accept contributions.
> The project requires a document on file but it doesn't accept that document from arbitrary people. It's effectively "by invitation only" and Richard hands out those invitations at his sole discretion.
I wouldn't classify it as disingenous, legalities are difficult, especially when you can't afford github's infrastructure and lawyers to write you up a CLA and a userbase that is not even aware of the TOS they're agreeing to. It's the only way to go.
if 99.99% of dev use Git you have to use Git, using your own solution that no one else uses or know or need to know is bad.
That's pretty much the opposite of progress.
At one time, 99.9% of developers used CP/M. At time, 99.9% of web was done in PHP. At one time, 99.9% of developers IBM XTs. At one time 99.9% of developers used SourceForce and SVN.
Stuff changes. Monoculture is bad for the tech industry.
On the one hand I'm inclined to agree about monoculture, on the other I've worked at a company where one employee dictated that we use bzr. Basically everything was an order of magnitude more difficult through minimal fault of bzr. None of the third party tooling worked with bzr, or if something did have bzr support it was dropped ages ago.
It's kind of the same situation with Github. The pain in moving away from it as they continue to slaughter the UX is still pretty great.
So yeah monoculture is bad but progress is painful.
Having been that person (albeit before Git was the one true way), I'm sorry. But seemed so nice and had solid externals and sparse checkouts back in the day. And as bad as it got for us, it still felt easier to pick up and use than early Git.
Sure, and I was that person with the svn -> git migration at a different gig. Ideally our behavior matures over time.
For me, at least, two things eventually made git really manageable: github and the O'Reilly book. After those git was a no brainer. Even with git becoming the de facto standard, if you don't need the integrations it's not so unreasonable to use something else (altho bzr's been discontinued).
I upvoted the post since I think it's a overall interesting technical discussion of git's downsides and some fossil upsides.
But my response would be the same as what I argue in these React or other "popular-vs-other-frameworks" discussions that come: the alternatives may be better, faster, easier etc - BUT:
- The popular solution has the larger ecosystem, and there are more existing plugins or modules you can plug-and-play instead of having to build out your own solution for.
- If you hit any edge case or obscure issues with the popular framework, someone somewhere on the Internet has hit it and it's likely a QA on Stackoverflow / Reddit and similar (and hence ChatGPT and other LLMs as a result)
- People understand the popular solution more in depth and it's easier to learn about the architecture as well as its pros and cons.
Counterpoint - I get the same spiel from SEO marketing people trying to justify why every website in the org (including LoB web apps, intranet sites, etc.) needs to be a WordPress instance with 50 or so insecure plugins each. "But it's so popular!".
> I think the explanation does not make any sense in 2023, if 99.99% of dev use Git you have to use Git, using your own solution that no one else uses or know or need to know is bad.
And this is why Microsoft is now in a monopoly position ... again ... simply by buying Github.
well, it is not that difficult to convert from one revision control system to another, at least among git, mercurial, bazaar and other equally featureful systems, which includes fossil too i would expect. maybe some of them are more featureful and track stuff that git doesn't so conversion would loose some data, but i don't see that as a problem. (a lesser system that doesn't track everything git has might be an issue, but actually not even that, since all we need is interoperability not full conversion)
mercurial has a plugin to support git, and the reverse exists too. for bazaar as well. interestingly fossil can export to git, and a git repo can be converted, but it can't pull updates from git into fossil. i wonder why.
anyways, the point is, because interoperability exists and is possible there is no technical reason not to use alternative tools despite everyone else using git.
> In contrast, Fossil is a single standalone binary which is installed by putting it on $PATH. ... It manages a community server with wiki, bug tracking, and forums, provides packaged ... Standing up a community server for Fossil takes minutes.
Let's see...
About a year ago I try to set up fossil because I wanted the issue tracking it supposedly provides. I'm already using git for VC and will stick with it.
Spend several hours and got nowhere. It's a local web-based thing and all I kept getting back was 404 Not Found. Did some reading around, found somebody had solved the problem by using --force option (IIRC, to force creation of a repo) but that didn't get me to anything actually working. The docs were unhelpful, as in wrong. Gave up. If you can't document your software then don't release it. Certainly don't make claims for its greatness and ease if you ignore what your users are saying on your message boards.
Make a repo. That's a file that lives wherever. Go to some directory, fossil open filename. Now you have a working directory. Type fossil ui, now you're looking at it in a browser.
It sounds like you want a version running on a machine that multiple people log into to access the UI. That I don't know how to set up. Spinning up the UI locally makes a lot more sense to me that sharing a single instance with the world.
> Make a repo. That's a file that lives wherever. Go to some directory, fossil open filename. Now you have a working directory. Type fossil ui, now you're looking at it in a browser.
Don't remember where I got to, I think --force got me a repo finally but the browser, well, I just got 404 then gave up.
> It sounds like you want a version running on a machine that multiple people log into to access the UI
Nope, mine is a one-man project, simple as you like.
I've been getting the hang of darcs recently. There's been your typical hiccups of learning something new, but it’s been an interesting process. I wouldn’t be surprised to see a Patch Theory-based DVCS be the Git successor, & if true, darcs will be the early inspiration and the terminology would likely be copied from darcs when in doubt so it doesn’t feel like a waste to learn. It’s definitely not a beta software supporting all the necessary basics for DVCS. Considering my biggest gripe is reliance on a Haskell module for SSH that doesn’t support ed25519 keys, there aren’t many issues.
i guess you use what you have, and don't use what you don't have, but i don't really know when i've ever thought let me see what happened after that branch was merged into future.
I do have a simple script that will list what branches were merged into the current branch in git. That is useful, so being built in, in Fossil is useful i guess.
My gripe with Fossil, is not technical, it is really just who uses it? How much support does it get. When will it wither and die? Maybe that is an invalid concern on my part. But that is way more important to me than any technical issues raised here.
Given that fossil is an integral part of sqlite, it will wither and die when sqlite does.
It's also the perfect example and test of sqlite itself, an scm that is a one stop shop for the entirety of the project, remaining as responsive no matter the increase of the scm db itself.
I tried fossil a while back mostly because of the idea of tracking tickets in the SCM.
I have come to understand tickets are almost a means of communicating outside of the SCM and with software illiterates it's hard to get them to use any SCM.
The thing I want most to replicate in git is "technotes" - I can get partway there with tagging and a "notes" directory but there is a lot more road to go down
I don't remember a single git command by heart, just there are some icons in the lower right corner of my Visual Studio window and in VSC window and it's pretty obvious what to do.
Seems like a textbook example of NIH to me. By the time you understand git well enough to design a good replacement, you’re bound to be an expert and ought to appreciate more the design of git.
If you don’t like the lack of a good GUI or web application, you can just build one that works the way you want and still works with git.
That’s true for personal projects, which is essentially the case here. If this was a business, not so much.
I was probably too harsh in my initial message, but when I read the article and see reasoning along the lines of “git lacks a good UI for X, I hear there may be 3rd-party solutions to this problem, but then that’s too many things to install, so I’d rather build a custom solution from scratch which does everything”, it reminds me of stuff I see at work ;)
Git came before Mercurial. Both git and Mercurial were spawned by the same event; BitKeeper revoking its free license for Linux kernel development.
Git development began 2005-04-03, and was self hosting on the 7th. The next minor release of Linux used git as its SCM. Mercurial was announced on 2005-04-19, and has been self hosting since 2005-05-03.
As someone who used Mercurial for many years when I worked at a company that used because they used BitBucket, you are overblowing the situation.
The CTO was very vocal about how Mercurial was better, but all the use cases he toted weren't really that meaningful. Eventually when BitBucket removed Mercurial support we switched to git. I'd used git previously and hadn't really understood the advantages of hg, and after we switched to git there was no difference in productivity.
Mercurial wasn't better, it's just slightly different enough to have a holy war over.
I thought they both started at the same time? Unless you are implying early versions of git were worse, which wouldn't surprise me.
I know git has a learning curve, but the only times I really see junior people have issues is when they are trying to do things that wouldn't have been easy with earlier VCS systems either. And it seems like git isn't going away, so it's worth putting the time into learning it.
git has been around since 2005. It's ubiquitous. And yes, I think it's a short-sighted and not-great decision to build your own version control system. Whether you're the lead developer of the unix kernel or just some guy writing your own scripts, it's not a good decision. Your title doesn't have much to do with that.
> and if you take the time to learn it, SIMPLE models for version control.
... And there it all falls apart. In practice, git requires a massive amount of learning to use competently, to the point that using something else just to avoid the learning curve is fairly reasonable.
As someone who has learned the ins and outs of git, I struggle to think of a better model for revision control. I never have issues with it anymore, and it took maybe a day to learn how it works under the hood. There's a great article on git internals directly in the git manpages.
I forced myself to learn it as a junior dev. Was it tough? Sure. But my point is that if it's too daunting and frustrating—software development holds nothing but pain for you.
Site worked fine for me, but in any case, SQLite is 23 years old now and widely used all over the place and well understood by many thousands of developers... the time has long since passed when its reputation might hinge on the moment-to-moment uptime of its own home page.
It's probably not availability issues. From what I've seen in Fossil discussions, sqlite.org is just a couple of Fossil instances (code and documentation) and a pack of HTML pages behind a simple web server. They had to invent an ad-hoc scrape protection for computationally expensive requests, and probably have something like that for DoS protection. It is possible that it is not fair because of simplicity, and temporarily blocks certain amount of less lucky visitors. Intermittent inaccessibility of project websites seems regular to me.
But often time when I tell juinors that when they're my age, git will be distant a strange memory to them, they look at me funny. It's a wonderful tool and earned its success, but I'll be sad if it's our final take on the problem.