Hacker Newsnew | past | comments | ask | show | jobs | submit | mamcx's commentslogin

Yes, and is super easy.

I do like this: cron to run the backup and then rsync to https://www.rsync.net, then an after script that check it was run and post to my telegram the analysis.

That is.


Another good option is Restic, since snapshots let you go back in time. That is useful in case you accidentally delete/break something and you're not quite fast enough to restore from backup before the next cron runs.

Well, what means to support, truly, TVars?

Is easy, or hard?

Demand a new paradigm at large, or is only a inconvenience in the few places is used?

Because if the answer is "turns the language into Haskell" then is a big NOPE!


Here is a C++ STM based on the Haskell STM API:

https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n44...


Well, Haskell is a big language with lots of different aspects.

To nicely support TVars, it's good if your language can differentiate between pure code and code with side-effects. Haskell's type system is one way to get there; but eg something like Rust could probably also be coerced to do something appropriate.

Apart from that, you probably don't even need static typing to make it work well enough (though it probably helps). You definitely don't need laziness or Haskell's love of making up new operators or significant whitespace.


Check the dBase/FoxPro family. My nostalgia remember it fondly, and there was not disconnected in how everything worked (example: The forms were stored as tables, so you can do alike `SELECT * FROM form_name WHERE widget=`), and there was zero ORM.

This is my aim https://tablam.org.

BTW I worked in SpacetimeDB and I proudly say is half-way :)


I have an invoice/order taker https://www.bestsellerapp.net, it syncs to many ERPs and allow people to operate everywhere, that I'm upgrading to be a more general mini-ERP.

On the side, retaking https://tablam.org, that I have procrastinated because wanna provide a parser that work for editors (that is way harder than normal batch parsers!)


No, jj is super simple in daily use, in contrast with git that is a constant chore (and any sane person use alias). This include stuff that in git is a total mess of complexity like dealing with rebases. So not judge the tool for this odd case.

> in contrast with git that is a constant chore (and any sane person use alias)

I don't use aliases, I guess I'm insane?

Also 99.9% of the time, git "just works" for me. If I need to do something special once a year, I can search for it. Like I would with jujutsu.


One rarely needs more from git than `git add -A && git commit -m`.

I rebase stacked diffs all the time so jj makes my life so much easier because its rebasing is much more ergonomic than git.

this seems very easy in git tho how much easier can it get, do you have an example of each of them?

As someone else said, jj comes into its own when a reviewer insists you split your PR into many commits, because they don't want to review 13k lines in one chunk. In that case it is easier because there is no rebase. To change a PR commit in the middle of the stack you checkout a PR commit, edit it - and done. The rebase happened automagically.

Notice I didn't say "edit it, commit, and done" because that's another thing you don't do in jj - commit. I know, `git commit` is just a few characters on the cli - but it's one of several git commands you will never have to type again because jj does it without having to be asked.

If the rebase created a merge conflict (it could do so in any PR commit above the one you edited) - it's no biggie because jj happily saves merge commits with conflicts. You just check it out, and edit to remove the conflict.

Jj does grow on you over time. For example, when you start with jj you end up in the same messes you did as a git beginner, when you recovered with 'rm -r repository', followed by 'git clone git@host/repository.git'. Then you discover 'jj op restore' which compared to git's reflog is a breath of fresh air. And while you might at first find yourself chafing at the loss of git staging, you gradually get comfortable with the new way of working - then you discover `jj evolog`, and it's "omg that's far better than staging". Ditto with workspaces vs worktrees, and just about everything else. It might be difficult to lose work with a bad git command, but actually impossible to lose work with a jj command.

It is a steep learning curve. We are talking months to use it fluently instead of treating it as git with better porcelain. If all you ever do is work with one commit at a time, it's a lot of effort for not a lot of return. But as soon as you start managing stacks of changes, duplicating them, splicing them, it makes you feel like a god.

That said, if you are starting out - I'd suggest starting with jj instead of git. You've got to go through a learning curve anyway. You may as well do it with the kinder, gentler, more powerful tool.


> That said, if you are starting out - I'd suggest starting with jj instead of git

That wouldn't be my advice if you're going to work with other people. You can't know jj without knowing git well enough to fall back in general


Git rebases don't work if there are conflicts, jj doesn't have this problem. Also idk if you can rebase onto multiple parents with git but jj can do it.

Can you explain how conflicts are not conflicts?

If I change a line of code several times and rebase on to a branch that changed the same lines of code, how are you sure what the right one is?


JJ can save conflict related state with the change so that you don't need to resolve a conflict in the middle of a stack of changes for rebasing to continue for the remaining changes. Concretely, it uses a "conflict algebra" where it can track the impact of a conflict as it propagates through the stack of rebased changes: https://docs.jj-vcs.dev/latest/technical/conflicts/

But what does that bring? Your code won't compile as long as you don't fix the conflicts, so anyway you have to fix them when you rebase, right?


Not really very similar at all for the scenario discussed here. Rerere remembers how you have resolved a conflict before. It doesn't let you rebase a stack of commits that result in different conflicts. You will have to stop and resolve each conflict and then `git rebase --continue`.

However, the conflict algebra does remove many common uses of rerere. See https://github.com/jj-vcs/jj/issues/175#issuecomment-1079831... for a longer discussion.


Avoiding manual conflict resolution isn't really a good thing though - conflicts are an indication that multiple different changes affect some code and you really should think hard about what the combination of them should be. Even what git does automatically already can be dangerous.

I agree, but that doesn't seem relevant. I did not say the jj automatically resolves conflicts.

I prefer `git commit --patch` and having a full editor for commit messages rather than a command-line -m argument to encourage me to actually write something useful.

Now which is the best alternative?

Then is better to use copilot to get access to this? I have wondered if go with Claude directly or copilot...

> Duplicates in source data are almost always a sign of bad data modeling

Nope. Duplicates in source data(INPUT) is natural, correct and MUST be supported or almost all data become impossible.

What is the actual problem is the OUTPUT. Duplicates on the OUTPUT need to be controlled and explicit. In general, we need in the OUTPUT a unique rowby a N-key, but probably not need it to be unique for the rest, so, in the relational model, you need unique for a combination of columns (rarely, by ALL of them).


Senior Rust / Database Engineer

*Also open to do custom software development!*

Location: Medellín, Colombia Remote: Yes! Willing to relocate: No

Technologies:

* System engineer: Rust · query engines · programming languages · VMs · transactions · storage · performance optimization · data modeling · ERPs · Business Apps

* Databases: RDBMs · PostgreSQL · SQL Server · SQLite · SpacetimeDB

* Backend: Business logic · APIs creation · integration · orchestration · ETLs

* Additional: Python, F#, Swift, Web assembly, Git, Jujutsu, macOS, Linux (NixOS, Debian), Windows

Résumé/CV: https://www.linkedin.com/in/mario-alejandro-montoya-cortés-6... Email: mamcx@elmalabarista.com https://www.elmalabarista.com

Software engineer with 30+ years building production-ready business applications and 3+ years as a core database engineer building high-performance RDBMs.

Founder and principal engineer of small ISV with a long track record of owning complex systems end-to-end, from low-level design to production reliability.

Driven to learn new domains quickly and choose the simplest effective architecture, tools and paradigms for each problem.


Seriously!

Why not show the names of the branch + short Id (and when is not direct name, at least "this is from NAME")


doesn't it? Next to the conflict markers, it'll display HEAD, the ref name, or the short commit hash.


I'll be honest, as a fairly skilled and experienced programmer who isn't a git expert, I know what HEAD means, but when I'm rebasing I really have no idea. It all seems to work out in the end because my collaborative work is simple and usually 2–3 people only, so I'm never rebasing against a ton of commits I lack context for (because 90% of them are my commits since I'm usually dealing with PRs to my open source projects rather than someone else's).

HEAD is "the thing we're editing now" but that's not terribly useful when rebasing since you're repeatedly editing a fake history.


Git leaks a lot of implementation details into its UX. Rebasing is meant to be equivalent to checking out the "base" branch and cherry picking commits onto it. Therefore "ours" during a rebase is the base branch.

The meaning of "ours" and "theirs" is always the same, but the "base" of the operation is reversed compared to what you might be used to during merge.

Rebasing can be confusing and hard and messy, but once I learned that rule and took the time to internalize it, I at least never got confused on this particular detail again.

> fake history

That's the thing, it's not actually fake history. Git really is doing the things it looks like it's doing during a rebase. That's why you can do all kinds of weird tricks like stopping in the middle to reset back a commit in order to make a new intervening commit. The reason you can abort at any time with (almost) no risk is because the old history is still hanging around in the database and won't be removed until GC runs, usually long after the rebase is settled.


Learning git properly is pretty much "read Git book at least 3 times".

All of it makes sense and is decently intuitive once you know how internals work.

People keep imagining git as a series of diffs while in reality it's series of the filesystem tree snapshots + a bunch of tools to manage that and reconcile changes in face of merge. And most of that can be replaced if the builtins are not up to task. And the experience is getting slowly better but it's balance between power users and newbies, and also trying to not break stuff when going forward.

Now of course that sucks if programming is not someone's day job but there is plenty of tools that present simpler workflows built on top of that.


Also git store (almost?) all its operations in the reflog. They have identifier like commits so you can reset to them and restore the original state of the working directory (mostly after an automatic rebase gone wrong).


That's the thing, they're not "like commits", they are the actual original commits. It's a history of where the HEAD ref used to be. Eventually those commits will be pruned out of the tree if/when the reflog expires because there is nothing left pointing to them. But otherwise they are normal commits.


I think what the grandfather comment meant is 'like' in the sense of 'this is an example'. Not 'like' in the sense of 'sorta / approximately'.


Yes, Git is like a Copy-on-Write filesystem.

It's interesting that once even C programmers, like Linus, become really experienced, they embrace the wisdom that functional programmers are forced to swallow anyway.


> HEAD is "the thing we're editing now" but that's not terribly useful when rebasing since you're repeatedly editing a fake history.

You got two things wrong here. Firstly, HEAD isn't 'the thing you're editing now'. HEAD is what you have already committed. If you want to edit the HEAD, you have to either amend the commit or reset and redo the commit. (To make the situation even more complex, the amended or overridden commit remains in the repo unchanged, but orphaned.)

The actual thing being edited is a 'patch' that will eventually be converted into a new commit (snapshot). If you're doing a rebase and want to see the next patch in the pipeline that you're editing now, try this:

  git rebase --show-current-patch
Secondly, rebase is not editing a fake history. Rebase is creating a new (and real) history by repeatedly cherry picking commits from the old history based on the rebase plan. HEAD is the tip commit of the new history under construction. On completion of the rebase, the branch ref of the old history is switched to the new history, where HEAD is now at. Meanwhile, the old history remains in the repo unchanged, but again orphaned.

All the orphaned commits are still visible in the HEAD's reflog. You can use it to undo the rebase if you wish.

I agree that the entire thing is confusing as hell. But I have a bunch of aliases and scripts that show you the process graphically in realtime. You can use that awareness to make the right call every time. I'm thinking about converting it into a TUI application and publishing it.


I avoid this problem by not rebasing.


Seriously! I have too many years of software development experience, but I use Visual Studio UX to handle pretty much all git operations. And always merge.

I have better things to do in my life than "internalizing" anything that doesn't matter in the grand scheme of things.


I don’t like that approach, because people who work like that commit all kind of crap to repo or cry that GIT ate their homework…

Then we have line ending conflicts, file format conflict UTF8-BOM mixes with just UTF8 it makes more work for everyone like crappy PRs. Because of people for who those are things that „don’t matter in grand scheme of things”.


I happen to know a lot about git internals, but I don't think everyone should need to.

About the line ending conflicts: set up your CI once to complain about those. And help your coworkers set up their editors right once.


If it hurts, do it more often.


Hey not every rebase has conflicts. I definitely rebase when there are no conflicts, then merge.

When there are conflicts I merge „theirs” into my branch to resolve those so I keep mental model for this side and don’t have to switch. Then rebase then open PR.


I do the following to keep my sanity when doing something like rebasing a feature branch onto latest origin/master:

* First and most important: turn on rerere.

* Second: merge and resolve all conflicts, commit.

* Third: rebase.

The second step might look redundant, but thanks to rerere git remembers the merge conflict resolution. That makes step 3 have fewer conflicts; and step 2 tends to be easier on me, because we are only reconciling the final outcomes.

(Well, I'm lying: the above is what I used to do. Nowadays I let Claude handle that, and only intervene when it gets too complicated for the bot.)


You could do all that. Or you could just merge every time. I know which I find easier.


It does now by default, since v2.12 (released 2017). Prior to that you had to set the log.decorate config. Good times.


It does


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: