Do you have a solution for auto-merging conflicting changes? Because I think that's the real difference, editing on a laptop and on a desktop before the sync can occur, can cause data-loss (for my potentially naive use of keepassxc anyway).
I've never seen this happen, because (as far as I can tell) all KeePassXC clients auto-save the file any time a change is made, and all the Nextcloud clients auto-sync as soon as the file changes. Keepass is also resilient to the underlying file changing while you have, say, the edit password dialog open.
If a conflict did happen though, newer versions of Nextcloud just keep both copies and alert you to resolve it. If I had to resolve this I'd probably try the built-in database merger first: https://keepassxc.org/docs/KeePassXC_UserGuide#_merging_data...
There are several factors at play making conflicts almost impossible:
- A central device can be immediately synced to. For Nextcloud, it could be a server, for direct synchronization that I use (Syncthing), my phone (almost always online) is the intermediate device for all.
- You are usually online when creating accounts/password, so an sync can happen directly after a change
- And finally: How often do you actually _create_ accounts rather than just read the database? And how often do you do it on two devices in quick succession?
Merge conflicts on NextCloud are terrible, but for a KeePass file, I don't think this comes up very much. My laptop syncs from Nextcloud whenever it's online, and my phone syncs whenever it opens or modifies the file. Nobody else is using my laptop or phone, and certainly not my keepass vault. I would probably have to go out of my way to use both my laptop and my phone offline and add/change passwords during that time in order to get a merge conflict.
How do you get data loss?keepassXC,DX saves a conflict copy and warns you. Anytime I've seen the warning over ~10 years it's been a non issue. Like I add an entry on PC, walk away from the 'save db' prompt for a day and then update something on my phone so I have 1 new account on both. I see the warning and so I have to hit one button to do the basic merge or whatever and it's done.
I think as compilers got smarter, UB changed somewhat in meaning. Originally the compilers didn't perform such complex analysis, and while invoking UB could break your program, it would still do something reasonable.
You see a reasoning here, basically when all those C compiler benchmarks started, vendors moved from what Frank Allen described, to anything goes to win SPEC something benchmarks.
"Oh, it was quite a while ago. I kind of stopped when C came out. That was a big blow. We were making so much good progress on optimizations and transformations. We were getting rid of just one nice problem after another. When C came out, at one of the SIGPLAN compiler conferences, there was a debate between Steve Johnson from Bell Labs, who was supporting C, and one of our people, Bill Harrison, who was working on a project that I had at that time supporting automatic optimization...The nubbin of the debate was Steve's defense of not having to build optimizers anymore because the programmer would take care of it. That it was really a programmer's issue.... Seibel: Do you think C is a reasonable language if they had restricted its use to operating-system kernels? Allen: Oh, yeah. That would have been fine. And, in fact, you need to have something like that, something where experts can really fine-tune without big bottlenecks because those are key problems to solve. By 1960, we had a long list of amazing languages: Lisp, APL, Fortran, COBOL, Algol 60. These are higher-level than C. We have seriously regressed, since C developed. C has destroyed our ability to advance the state of the art in automatic optimization, automatic parallelization, automatic mapping of a high-level language to the machine. This is one of the reasons compilers are ... basically not taught much anymore in the colleges and universities."
-- Fran Allen interview, Excerpted from: Peter Seibel. Coders at Work: Reflections on the Craft of Programming
As a counterexample, I've been seeing more "safety rejections" from Claude. Unlike search, being unable to ask _anything_ about botulinum, or details about the recent Copy Fail vulnerability (without giving my fingerprints to Anthropic to become a "verified security researcher") we're only just beginning to see the ways LLM can be used to distort information and its availability.
I don't think it's been co-opted? Mirroring the emotions of another person you're actively observing doesn't give you insight into why they're feeling that way. It's just mirroring, but its an excellent starting point for learning. To have empathy, for people you're not actively observing, or for future states of people you are observing, you have to be able to model them first, and then mirror the emotions that the model predicts, which can then update the model. This loop is empathy, its both "experiencing other's emotions" and "the ability to understand and predict".
If you don't provide it a <tree-ish> it reads from the index (staged files). So you're right its not really pointed anywhere, since the index isn't a ref.
That's my overall point: the argument itself (with respect to the current state of the repo) is what determines the behavior. I don't think this is anywhere close to as intuitive as commands that only ever accept one "type" of argument (and erroring if it's different).
I stand corrected by this one scenario, but I’ve been using git for over a decade and never found that useful. Just don’t use checkout on a file path, there is no need.
I find this kind of advice to be a more scathing indictment of an interface than a critic could ever muster: asking users to forego available functionality so that some sense of order can be imposed.
That goes in the same bucket as rebase. Until you know what it does, you'll be fine avoiding it.
Since people are sharing their experiences and my recent one is relevant to edit, I'll go:
Working on a feature recently, I ended up making 3 changes ("commits") on top of each other and hopping between them via jj edit.
The first change wasn't feature specific, it was extending the base project in preparation.
The second change just added a doc describing all the changes needed for the feature.
The third change removed the doc as parts were implemented, bit by bit.
As I progressed on the third change & found stuff I'd missed at the start of this process, I jumped back to edit the first change (maybe I had a bug in that base project extension) and the second change (oh hey, I found something else that needed to be done for the feature).
It sounds crazy compared to a git workflow, but at the end of the process I have 3 changes, all tested & working. If I was doing this with git, I'd have to rebase/squash to get the final changes into a neat clear history.
I suggested that since you seemed really concerned about editing the commit that you just told it to edit. Use 'edit' all you want if your goal is to edit commits, otherwise 'new' does what it seems like you're expecting...
edit is useful and there are good reasons to use it, 'never use edit' is like 'never use goto' i.e. false - but if you're just starting out, jj new/jj squash is the way to go indeed.
(my particular favorite reasons to use jj edit are git-native tools which expect to work with uncommitted files e.g. autoformatters, linters, etc. which have been scripted in CI/dev workflows such that they cannot accept a list of files as params)
"Just don't accidentally do things wrong" is also the way to avoid null pointer errors, type mismatches in dynamically typed languages, UB in C/C++. It works, until it doesn't, and in practice that happens pretty quickly. Personally, I like things that have proper safety checks.
Except it's not an unrecoverable error. If you do it all it does is add that file to the working index. No commits are made and no harm is done. So no, I do not feel it's the same as a null pointer exception or type mismatch.
> If you do it all it does is add that file to the working index.
No, that's not at all what it's doing!
git init
touch foo.txt
git commit -m 'empty foo.txt'
echo something >> foo.txt
git diff --stat # Shows one line added to foo.txt
git checkout foo.xt
git diff --stat # empty output; no changes!
It removes changes that are not yet checked in. You can only get them back by going into the reflog (which is pretty much identical to the situation described with `jj edit` at the beginning of this thread; `jj op log` will let you get them back fine).
edit: Actually, I was wrong; the changes will NOT be in the reflog because they were never checked in. It's fully destructive; you've lost the changes and don't have any way of getting them back through git. This is strictly worse than anything possible with `jj edit`, and even when making this point I didn't realize how bad it was, and clearly neither did anyone defending it.
The fact that there have already been two instances of defending git's behavior without even understanding what it's doing with this command is exactly my point. It's not your fault; the command is unintuitive, and that's my entire point. How many times should it take for people to try to explain what's happening incorrectly before we accept this?
It's a useful thing to be able to do! It just fundamentally shouldn't be under one command. To its credit, git did add `switch` (with `-c` for creating a new branch and `-d` for specifying detached HEAD), but after two decades I can't imagine they'll ever get rid of checkout entirely because it was so fundamental for so long, and as long as its there, it's a loaded footgun with the safety off.
If you don't run checkout on file paths, how do you undo changes to specific files that you haven't committed yet? Like you've edited but not committed <foo>, <bar>, and <baz>. You realize your edits to <bar> are a mistake. I'd just run `git checkout <bar>` to revert those changes, what do you do?
It is also really useful when you realize you want <bar> to be the version from a commit two weeks ago. I guess you could always switch to the branch 2 weeks ago, copy the file to /tmp/, switch back, and copy the file into place, but `git checkout c23a99b -- <bar>` is so quick and easy. Or does this example not fall under the "dont run checkout on a path" since it is taking a treeish first before the path?
Container tabs, independent proxy config (chrome only respects system-wide proxy), vertical tabs, and functional adblockers are the four big features for me.
Weapons are designed with an opponent in mind, and guarded against the expected threat models from that opponent. Everything breaks down when the opponent does not what you want them to.
reply