Well, I must say ChatGPT felt much more stable than Meena when I first tried it. But, as you said, it was a few years before ChatGPT was publicly announced :)
I think the important part here is "from scratch". Typically when you're designing a new (second, third, whatever) system to replace the old one you actually take the good and the bad parts of the previous design into account, so it's no longer from scratch. That's what allows it to succeed (at least in my experience it usually did).
These days software has been done a lot. You should be able to find others who have done similar things and learn lessons from them. Considering microservices - there are lots of people who have done them and can tell you what worked well and what didn't. Considering using QT - lots of others have and can give you ideas. Considering writing your own framework - there are lots of others: look at what they do good and bad.
If you are doing a CRUD web app for a local small business - there are thousands of examples. If you are writing control software for a space station - you may not have access to code from NASA/Russia/China but you can at least look at generic software that does the things you need and learn some lessons.
It's always November, isn't it? I've once made a log collection system that had a map of month names to months (had to create it because Go date package didn't support that specific abbreviation for month names).
As you might've guessed, it lacked November, but no one noticed for 4+ months, and I've left the company since. It created a local meme #nolognovember and even got to the public (it was in Russia: https://pikabu.ru/story/no_log_november_10441606)
> This might be on me and my lack of capacity to exploit the tools to their full extent. But, iterating over customer requirements, CI/CD, peer reviews, and business validation takes time (and time from the most experienced people, not from the AI).
Yeah, you're certainly not the only one. For me the implementation part has always been a breeze compared to all the "communication overhead" so to speak. And in any mature system it easily takes 90% of all time or more.
That reminds me of why I don't think that if err != nil in Go is actually a problem, because while it's annoying to have to pause each time an error can happen, it's actually very useful, because it forces you to consider all the possible failure states and it often lets you discover the flaws in your original design while you're typing in the code. This eventually leads to much better outcomes and allows for the tools I write to be much more resilient than they otherwise would.
Obviously it all goes out of the window as soon as AI coding comes into question, and that's why I learned that I actually _don't_ want AI to generate code for me. I would only ask it simple questions like "how do I do X in Go" or in some other system, but the implementation I do myself, otherwise I lose this "having to consider every error path" part, which is apparently very helpful when your goal is to write resilient software
In iOS we can only use something like ish.app which emulates x86 and runs full Linux distro instead, with predictably much lower performance than Termux (due to JIT being banned in iOS apps), but without any restrictions Android has on the executables
iSH is great as an ssh client. It has a good font out of the box, so it displays tmux and neovim properly.
a-Shell should be faster than iSH for local stuff since the tools are compiled natively, but nothing on iOS, as far as I know, compares to Termux on Android.
Elsewhere in this thread, someone mentioned that ISH is a full PC emulator running Alpine. You wouldn't necessarily need JIT or native execution for a software VM.
UTM can't be installed from the App Store unfortunately, and without a developer license you are limited to 7 days for each successful on-device reinstall
Nice, I must've missed that. Downloading it right away :)
Edit: well, it's also very slow unfortunately. I believe iPhone CPUs either don't support virtualisation or they don't expose it (edit #2: it's the latter). Either way, QEMU is struggling quite a bit, and due to it being a GUI it's even slower than what iSH could do
As a backend engineer I really like where all of this is going. In many many cases you do not need anything beyond what HTMX provides, and it makes the build and testing process so much simpler, and faster too
There are cases where you need more than htmx / datastar, but i like the explicit calling out of when these boundaries occur (e.g. you've exceeded what "islands" can give you), and i like the gravitational pull to lower levels.
The limitations of HTMX are not the same as the limitations of Datastar. Datastar is a whole other beast with only a few at most vestigial similarities to HTMX.
You can't do virtual scroll over a billion checkboxes in HTMX (I've yet to see anyone manage in react for that matter either), yet you can do it easily in Datastar. [1]
Thanks Carson. Although honestly it's pretty mid compared to what's actually possible in hypermedia.
The only reason I wheel it out is when people say you can't do X (often meaning react like things) with hypermedia.
Honestly, you could probably do it in HTMX if you are prepared to only use out of bounds swaps, morph and SSE. But, that approach has always felt second class, unfinished and against the grain. So stuff like that isn't done.
Always made me sad that you wrote idiomorph (thanks for sharing it with the world) but didn't make it part of HTMX. I guess HTMX 4 will change that?
Nice work! On a complete tangent, Git is the only SCM known to me that supports recursive merge strategy [1] (instead of the regular 3-way merge), which essentially always remembers resolved conflicts without you needing to do anything. This is a very underrated feature of Git and somehow people still manage to choose rebase over it. If you ever get to implementing merges, please make sure you have a mechanism for remembering the conflict resolution history :).
I believe rerere is a local cache, so you'd still have to resolve the conflicts again on another machine. The recursive merge doesn't have this issue — the conflict resolution inside the merge commits is effectively remembered (although due to how Git operates it actually never even considers it a conflict to be remembered — just a snapshot of the closest state to the merged branches)
Are people repeatedly handling merge conflicts on multiple machines?
If there was a better way to handle "I needed to merge in the middle of my PR work" without introducing reverse merged permanently in the history I wouldn't mind merge commits.
But tools will sometimes skip over others work if you `git pull` a change into your local repo due to getting confused which leg of the merge to follow.
One place where it mattered was when I was working on a large PHP web site, where backend devs and frontend devs would be working in the same branch — this way you don't have to go back and forth to get the new API, and this workflow was quite unique and, in my mind, quite efficient. The branchs also could live for some time (e.g. in case of large refactorings), and it's a good idea to merge in the master branch frequently, so recursive merge was really nice. Nowadays, of course, you design the API for your frontend, mobile, etc, upfront, so there's little reason to do that anymore.
Honestly if the tooling were better at keeping upstream on the left I wouldn't mind as much but IIRC `git pull` puts your branch on the left which means walking history requires analysing each merge commit to figure out where history actually is vs where a temporary branch is.
That is my main problem with merge, I think the commit ballooning is annoying too but that is easier to ignore.
Rerere is dangerous and counterproductive - it tries to give rebase the same functionality that merge has, but since rebase is fundamentally wrong it only stacks the wrongness.
Yeah, the point about high complexity of the recursive merge is valid, and that's what I would expect from the Mercurial devs too. I personally find it a bit unfortunate that Git ended up winning tbh, but since it did, I think it makes sense to at least cherish what it has out of the box :)
In some ways, the legacy of mercurial lives through jujutsu/jj and offers some sanity and familiarity on top of git's UI. But with that said, mercurial is far from dead, major "under-the-hood" works are going strong (including a rewrite in rust), the hosting situation is getting good with heptapod (a branch of gitlab with native mercurial support).
I really don't see any downside to recommending mercurial in 2026. Git isn't just inferior as a VCS in the subjective sense of "oh… I don't like this or that inconsistent aspect of its UI", but in very practical and meaningful ways (on technical merit) that are increasingly forgotten about the more it solidifies as a monopoly:
- still no support for branches (in the traditional sense, as a commit-level marker, to delineate series of related commits) means that a branchy-DAG is border-line useless, and tools like bisect can't use the info to take you at the series boundaries
- still no support for phasing (to mark which commits have been exchanged or are local-only and safe to edit)
- still no support for evolve (to record history rewrites in a side-storage, making concurrent/distributed history rewrites safe and mostly automatic)
Much more principled (and hence less of a foot-gun) way of handling conflicts is making them first class objects in the repository, like https://pijul.org does.
> Jujutsu keeps track of conflicts as first-class objects in its model; they are first-class in the same way commits are, while alternatives like Git simply think of conflicts as textual diffs. While not as rigorous as systems like Darcs (which is based on a formalized theory of patches, as opposed to snapshots), the effect is that many forms of conflict resolution can be performed and propagated automatically.
I feel like people making new VCSes should just re-use GIT storage/network layer and innovate on top of that. Git storage is flexible enough for that, and that way you can just.... use it on existing repos with very easy migration path for both workflows (CI/CD never need to care about what frontend you use) and users
Git storage is just a merkle tree. It's a technology that's been around forever and was simultaneously chosen by more than one vcs technology around the same time. It's incredibly effective so it makes sense that it would get used.
The bottleneck with git is actually the on-the-fly packfile generation. The server has to burn CPU calculating deltas for every clone. For a distributed system it seems much better to use a simple content-addressable store where you just serve static blobs.
It is my understanding that under the hood, the repository has quite a bit of state that can get mangled. That is why naively syncing a git repo with say Dropbox is not a surefire operation.
Lack of current-SCM incumbent compatibility can be an advantage. Like Linus decided to explicitly do the reverse of every SVN decision when designing git. He even reversed CLI usability!
Pssst! I think Linus didn't as much design Git as he cloned BitKeeper (or at least the parts of it he liked). I have never used it, but if you look at the BitKeeper documentation, it sounds strangely familiar: https://www.bitkeeper.org/testdrive.html . Of course, that made sense for him and for the rest of the Linux developers, as they were already familiar with BitKeeper. Not so much for the rest of us though, who are now stuck with the usability (or lack thereof) you mentioned...
New to me was discovering within the last month that git-merge doesn't have a merge strategy of "null": don't try to resolve any merge conflicts, because I've already taken care of them; just know that this is a merge between the current branch and the one specified on the command-line, so be a dutiful little tool and just add it to your records. Don't try to "help". Don't fuck with the index or the worktree. Just record that this is happening. That's it. Nothing else.
This resolves any number of heads, but the resulting tree of the merge is always
that of the current branch head, effectively ignoring all changes from all other
branches. It is meant to be used to supersede old development history of side
branches. Note that this is different from the -Xours option to the ort merge strategy.
The name "null" is confusing; you have to pick something. However, I think what is desired here is the "theirs" strategy, i.e. to replace the current branch's tree entirely with the incoming branch's tree. The end result would be similar to a hard reset onto the incoming branch, except that it would also create a merge commit. Unfortunately, the "theirs" strategy does not exist, even though the "ours" strategy does exist, apparently to avoid confusion with the "theirs" option [1], but it is possible to emulate it with a sequence of commands [2].
Neither of these are answers or explainations. So you said nothing, and then said nothing again.
I also "mean what I wrote". Man that was sure easy to say. It's almost like saying nothing at all. Which is anyone's righ to do, but it's not an argument, nor a definition of terms, nor communication at all. Well, it does communicate one thing.
> don't try to resolve any merge conflicts ... Don't try to "help". Don't fuck with the index or the worktree.
... certainly is "nothing" in the literal sense--that that's what is desired of git-merge to do, but it's not "nothing" in the sense that you're saying.
git reset --hard has nothing to do with merging. Nothing. They're not even in the same class of operations. It's absolutely irrelevant to this use case. And saying so isn't "not an argument" or not communicating anything at all. git reset --hard does not in any sense effect a merge. What more needs to be (or can be) said?
If you want someone to help explain something to you, it's up to you to give them an anchor point that they can use to bridge the gap in understanding. As it stands, it's you who's given nothing at all, so one can only repeat what has already been described--
A resolution strategy for merge conflicts that involves doing nothing: nothing to the files in the current directory, staging nothing to be committed, and in fact not even bothering to check for conflicts in the first place. Just notate that it's going to be a merge between two parents X and Y, and wait for the human so they have an opportunity to resolve the conflicts by hand (if they haven't already), for them to add the changes to the staging area, and for them to issue the git-commit command that completes the merge between X and Y. What's unclear about this?
This will initiate a merge, take nothing from the incoming branch, and allow you to decide how to proceed. This leaves git waiting for your next commit, and the two branches will be considered merged when that commit happens. What you may want to do next is:
git checkout -p <branch>
This will interactively review each incoming change, giving you the power to decide how each one should be handled. Once you've completed that process, commit the result and the merge is done.
You are confused. It's frightening that someone would be able to reach a point this deep into the discussion and think that "You know that you can edit your merge commits any way you want and you don't have to rely on resolution strategies to do it for you" is revealing something new or insightful.
I hate git squash, it only goes one direction and personally I dont give a crap if it took you 100 commits to do one thing, at least now we can see what you may have tried so we dont repeat your mistakes. With git squash it all turns into, this is what they last did that mattered, and btw we cant merge it backwards without it being weird, you have to check out an entirely new branch. I like to continue adding changes to branches I have already merged. Not every PR is the full solution, but a piece of the puzzle. No one can tell me that they only need 1 PR per task because they never have a bug, ever.
Give me normal boring git merges over git squash merges.
as far as I understand the problem (sorry, the SO isn't the clearest around), Fossil should support this operation. It does one better, since it even tracks exactly where merges come from. In Git, you have a merge commit that shows up with more than one parent, but Fossil will show you where it branched off too.
reply