Dura is a background process that watches your Git repositories
github.com
github.com
I find it's helpful for not losing work / easily backing up if as I'm going along I realize I want to change approach.
(For the micro commit I have a git command "git cam" that just commits all changes with the message "nt". Then once I'm ready to do a "real commit", I have "git wip" which rolls back all the nt commits but leaves them in checkout; then I can make one or two "real" commits.)
I wonder if dura would be even better, or if the commit frequency would end up being too fine-grained and obscure?
git status && git add -A git commit -m "checkpoint" --no-verify
I include `git status` so I can see what's being committed. `--no-verify` is used to skip any pre-commit hooks.It's a handful of commands because git-cam and git-wip referenced other little utility scripts, so hopefully I got them all. Probably it would be easy to rewrite to be standalone.
I'm on a mac, and I have ripgrep installed as "rg". Ymmv, glhf :-)
So:
"git cam" commits everything with message "nt"
"git wip" undoes all the nt commits but leaves the results staged, ready to be commited as a single properly worded commit (or play w/ what's staged and do as several commits)
This breaks down sometimes if you have to switch back and forth between different parts of code, breaking the linear sequence. But even then, the messages make it easier to connect the pieces when it's time to clean up history before the pull request.
also, sometimes I just lump the whole thing into a PR because there arent more than one logical unit.
(... but of course, by all means do what works for you. Just be aware that you might be missing out on something because you're artificially constraining your workflow.)
I also don’t use an IDE.
You don't need to have even remotely working code when you commit, is the point. You just commit whenever. (It's almost like saving files, just commit.)
I think the word 'commit' might have been a mistake, now that I think about it. Maybe 'snapshot' would have been better.
This works well for my workflow because we squash all commits into target branches and don't really rely on commit history auditing during review. I understand that's not the case everywhere, but works for me.
edit: added question
I.e. just use "git add -A" instead of "git cam"
Then you don't need "git wip"
It annotates the checkpoints with metadata as well. Like "this is how the file looked when you ran a test that failed".
Repo here: https://github.com/zabel-xyz/local-history
Doesn't appear to mark checkpoints with metadata, though (test failed/passed, etc.).
But I can see times where Dura could be kind of nice. When I'm doing CAD or other not-very-source-code things, having a few snapshots be grabbed along the way sounds nice. Going to try and git commit in intermediate states feels a little too mode-switchy to me.
(I use just external scripts rather than git aliases because I find it a little nicer to work with; git has a feature where if you enter "git foo", it will look for a command "git-foo" to execute.)
This is pretty much my workflow, too. I’ll make some changes, `git commit -m wip`, and then `g can`. When you’re ready to prepare the PR/diff, `reset HEAD^`. Then, a few cycles of `add -p`, `commit -v`.
`commit --amend` and `add --patch` are super powers!
I must avoid those situations by making a new commit when I anticipate wanting to keep the reference to that point in work accessible.
I do dive into `reflog` maybe once or twice a quarter, but as far as I can remember, I only go there as an immediate reaction to tired-brain mistakes.
Then when I'm ready to commit or cut PRs, I just squash them all down if it's trivial. If it's a bigger change: I push things to a backup branch, `git branch Branch-BK`, reset to a base commit, and use difftools to pull over the subset of changes I want and commit them repeatedly until there's no diff left.
https://gist.github.com/nicois/e7f90dce7031993afd4677dfb7e84...
Aren't you describing a feature branch? That frankly sounds like git 101.
What OP describes is a temporary work branch that belongs to a single person, and has a bunch of meaningless commits. So nobody else should be using it - or if they do, they need to sync with the owner, since the latter can squash or otherwise mutate commits at any time.
No, not really. In fact, some issue tracking software equate feature branches with tickets, worked on by a single person.
> What OP describes is a temporary work branch that belongs to a single person, and has a bunch of meaningless commits.
Aka a feature branch.
Edit: I guess my script is somewhere between your `git cam` command and Dura in terms of functionality and complexity.
Both save uncommitted changes in a hidden ref.
Based on the README, the differences seem to be:
1. dura runs as a daemon while git-sync-changes is a one shot execution.
2. dura saves locally, while git-sync-changes syncs with a remote repo.
3. dura only does the save and the restore is manual, whereas git-sync-changes does both steps automatically.
I’m glad to see more people exploring this space. I think there’s a lot of untapped potential in tracking pending changes similarly to how we track committed changes.
Which saves all uncommitted changes to a tag.
I wrote it because I wanted to have a complete snapshot of a build context. Sometimes composer or npm can't be relied upon to reproduce dependencies in the state they used to be, or I just want a cache of artifacts. It has been pretty handy.
It sounds like it addresses roughly the same use case, but I couldn’t find any technical details about it in its docs in order to see how it compares.
It's kind of insane to that in 2022 were still dealing with "save early, save often."
Our tools are so antiquated. Storage is cheap and computers are fast, every keystroke should be persisted somewhere I can recover from rather than having to manually save and commit works in progress.
I pretty much never save anything with Page/Numbers/TextEdit. I just quit
Not only do I not lose changes, I don't lose editions. I can go back to older versions. And that's not including Time Machine. It's simply "built in".
From a user experience, it's really wonderful and no stress. I don't even think about it. At the same time, I have no idea where these extra versions are stored but, honestly, I don't care.
I do wish other applications worked similarly. Source code is tricky, but it probably wouldn't be awful to have a similar experience.
[0]: vim and emacs, at least.
"When Ctrl-Z is not enough"
As a french, I can only call this service Patricia. Because Patricia Kaas of course.
[0]: https://vimhelp.org/undo.txt.html#undo-tree [1]: https://github.com/mbbill/undotree
Those of us who don't code in autosynced folders, that is. There is tons of software (IMO better than the approach in TFA) that has solved this problem for years now. Dropbox or Google Drive if you trust the cloud. Unison or looping rsync or syncthing if you don't.
Perhaps it was intended, but I can’t quite make a connection.
Dura is also an anatomical term for the tissue encasing the brain.
Apparently it left quite an impression on early anatomists/neurosurgeons.
I had originally named it "duralumin" after a magical metal in [a novel that I'm reading](https://www.amazon.com/Well-Ascension-Mistborn-Book/dp/07653...). I shortened it to "dura" after realizing that I can't even remember the name, so there's no chance anyone else will. Plus is has that "durable" vibe to it, which seemed appropriate.
FWIW the same word "dura" may also be used as a slang word for a large and unwieldy inanimate object.
I’d just never heard of it before.
There are many things to build on top: - Squash history so that it doesn’t grow indefinitely. - Be somewhat language aware to provide better commit messages - IDE integration
(A long-time fossil contributor here.)
Fossil has no such feature. Fossil sync synchronizes the remote and local saved state (checked-in/saved state only). It does not do anything with un-checked-in state.
That said, you can use fossil's stash to periodically take a (non-sync'd) snapshot using something like 'fossil stash snapshot -m "snapshot @ $(date)"' (i have that aliased and use it often). That does not enter the SCM history and is lost if you destroy the checkout dir.
‘sgbeal and I were doing some fossil dev work ourselves (I’m personally not at his level of fossil-fu, but am a long-running user and contributor). Our work was in a fossil repo (he in Europe, me in North America) and we were using the chat[0] feature to discuss our work when we noticed and discussed the GP post. Fossil has been self-hosting for ages, now is it self-correcting? /s
Git can operate on two local repos reasonably efficiently, IIRC, so diffing and applying commits should be doable.
Would you mind creating a Github issue? The project could benefit from more discussion around this.
Lately, I've been using private branches in the early stages of feature development, but you still have to remember to push in case of hardware failure. I also rely on my IDE's local history to get back to a good place if I need it.
I wonder if it would be good to combine these ideas: commit and automatically push every N minutes. Is this something that's being considered for Dura? Or is it a bad idea?
One big challenge must be avoiding commits when someone's right in the middle of typing, although having to stitch a couple adjacent commits together would definitely be better than losing work.
Automatic pushing is also probably not great. If it's just a backup mirror of some kind maybe, but otherwise you should be doing something like intentionally pushing what you're trying to share.
I don't really think that backups should be tied to git. There's already good backup software, wiring it into git doesn't seem to add anything.
For this type of ephemeral backup of code-in-progress, I think storing it in git would be really convenient, because you'd just use standard git commands to find what you're looking for without having to deal with another tool.
watchexec -c -e go 'go test ./... && git commit -am "Tests pass"'
:set backup
:set backupdir=/home/kaz/.vimbackup
:let &g:backupext=("." . strftime("%y-%m-%d.%H:%M:%S"))
That's it. No messing around with git; protects files that are not in git, and can save you even in he face of "rm -rf .* *". (setq backup-directory-alist `(("." "/home/user/some/dir/you/chose/backup/))
version-control t
kept-new-versions 50
kept-old-versions 50)
sets up a directory with many versions of every file ever edited. Additionally (setq auto-save-file-name-transforms `((".*" "/home/user/some/dir/you/chose/auto-save/" t)))
does the same for even unsaved changes. :au BufWritePre * let &backupext=("." . strftime("%y-%m-%d.%H:%M:%S"))
This has the right effect that every time you save with :w, a new backup is made of the previous contents.I want my VCS commits to be intentional. If they’re not then I’m just using a fancy VCS tool[1] for backup—just set up a _dumb_ backup routine that backs up every X interval and doesn’t have to care about the intentionality behind any changes made (the domain of version control).
And if you get into a situation where you haven’t committed for such a time while that you risk losing “days of work” then… seriously? You might want to get a better Git client where committing isn’t such a pain (IMO the CLI is too much typing for git(1). Magit is great).
And as already mentioned there is the reflog. Which is difficult enough for me to navigate sometimes without some pseudo-backup tool making a mess (on top of _my_ mess…).
[1] Git might be “stupid” but it’s also quite fancy.
Yes you are; what's wrong with that?
It's better to keep the two things separate. I'm happy with Backblaze on all my machines - although they have a disturbing habit of making unannouced changes to their default exclude filter which tripped me up (no VM images I knew about. But adding .git directories nearly lost me data). You can override these filters but they really shouldn't be changing them without clear warning.
1. everything else on your system (potentially - a lot of stuff depending on your workflow
2. everything you've .gitignored (you 100% sure that's all ok?)
3. changes not yet pushed
4. branches that don't exist on remote
5. git stuff that's invaluable for disaster recovery
6. git stashes
and probably other things i haven't thought of.
Backups should be:
1. Offsite
2. Automated
3. Recent and up to date
4. Comprehensive
Git workflows usually only handle point 1
You’re thinking about commit wrongly. You should commit all the time, and make use of branches liberally, and push branches to a remote for backup. Then, you should form your “permanent” commits from that work. The thing is, you have to get comfortable with git. For example, one common move is:
1. Commit everything 2. Make a temp branch (remember that “branches” are just labels for a commit; they cost nothing) 3. Switch back to the first branch 4. Use git reset to uncommit the last few commits 5. Clean up the code and commit it properly, with a good commit message 6. Run tests and check the diff from your temp branch to check you didn’t make a mistake when cleaning up
This tool Dura is totally unnecessary for people who are comfortable with git.
I agree - but that doesn't invalidate my original statement. I think you might have misunderstood my point. See my other reply above.
1. A large number, possibly a majority, of people who aren't yet familiar enough with git. Those people think of commits as being final: a commit is what you will push to the remote, your colleagues will see, and gets stored in public git history forever. They haven't yet learned that branches cost nothing, how to work with temporary branches, and how to create a new series of commits from already-committed work.
2. People who know git well and are the complement of the above set in all ways.
I'm sure you're right that backup systems have their place, but your comments here about how git shouldn't be used for backups are aligning with the camp (1) folks and making it harder for them to see that git can be used to save their work frequently, once they learn git better. Ultimately, positions like the one you're taking contribute to people developing misconceived tools such as TFA.
> 1. everything else on your system (potentially - a lot of stuff depending on your workflow
Sure -- backing up random files is good. I use google drive for that personally.
> 2. everything you've .gitignored (you 100% sure that's all ok?)
Yes, I don't worry about this. .gitignore is itself under git's control, so whatever's gitignored for me, is gitignored for my colleagues, therefore the project works without standardized content in those file paths.
> 3. changes not yet pushed
What reason is there ever to not push a branch that contains work you wouldn't want to lose? Planes and other no-network situations is one: I just push as soon as I'm on network. I never leave valuable work unpushed if I have a network connection.
> 4. branches that don't exist on remote
Why haven't you pushed them?
> 5. git stuff that's invaluable for disaster recovery
Not sure what you mean here
> 6. git stashes
Yes, good point to raise. Store work you're not prepared to lose in branches, and push them. You can stash it as well if that's convenient.
You probably know this, but the biggest hurdle newcomers to git face is they don't understand that branches are cheap, and they don't understand how easy it is to undo changes by using temp branches with `git reset --hard` and `git checkout`. Rather than telling them to supplement git with a backup system, it would be better to teach them to get comfortable using git. TFA is an extreme example, talking as if ctrl-z undo is an inevitable workflow for a git user when, in fact, it's only something that beginners do for more than trivial undo operations.
I don't trust any backup that requires me to remember and take a manual action.
> > 3 . changes not yet pushed > > 4. branches that don't exist on remote > Why haven't you pushed them?
Fair point. Because I'm mainly working in public repos, it's psychological. It requires some degree of mental effort whenever I think about pushing something because it's then in public for people to see. I judge people on their public commits so I rather suspect people will do the same as me. "Naming things is one of the hard problems in computer science" - a public commit requires several naming decisions (commit message, branch, deciding "foo" is not a great name for a variable). I sometimes don't want to break my flow to make those decisions. And sometimes that means I put off a commit for longer than I should.
Whereas - my backup happens automatically and continually. It's not tied to my indecision, choices or personal failings. It just works.
So - I strongly recommend everyone uses version control. And I strongly recommend they augment it with AUTOMATIC off-site backups.
> I don't trust any backup that requires me to remember and take a manual action.
(Google drive has an automatic sync client thing like Dropbox so all it involves is having a special local folder where I put documents I want backed up. Or indeed git repos. https://www.google.com/drive/download/)
One last point. A backup shouldn't be "a special local folder" - it should be "all files on all drives unless I specifically exclude them"
My backup is "the cloud". It's a remote store of my stuff.
I've got about 6tb of local storage attached to my two machines. I couldn't afford Google Drive or similar for that.
https://github.com/wtpayne/hiai/blob/master/a3_src/h70_inter...
ssh root@remotehost 'apt install -y zfs-auto-snapshot'
while sleep 1 ; do rsync -avP ~/Documents/ user@remotehost:Documents/ ; doneI prefer not rebasing / editing unless I have to.
The 'master' file was the one on the local HD.
That reporter was me.
M-x recover-this-file
https://www.emacswiki.org/emacs/AutoSavePeople are thinking about commit wrongly. You should commit all the time, and make use of branches liberally, and push branches to a remote for backup. Then, you should form your “permanent” commits from that work. The thing is, you have to get comfortable with git. For example, one common move is:
1. Commit everything
2. Make a temp branch (remember that “branches” are just labels for a commit; they cost nothing)
3. Switch back to the first branch
4. Use git reset to uncommit the last few commits
5. Clean up the code and commit it properly, with a good commit message
6. Run tests and check the diff from your temp branch to check you didn’t make a mistake when cleaning up
In my experience there’s a lot of Git tools out there that basically exist because people don’t want to read the manual. But seems like Dura is not one of those.
True! Stash is one of those things, right? Does dura catch the stashes specifically? Clearly it’ll catch whatever work you did before stashing, but if it saved stashes specifically in it’s own thing, that would be extra handy.
You may want to look at turning this into a systemd/launchd service so the OS can launch the tool on boot and handle restarting it on crashes.
I use VSCode and if my computer crashes it'll just recover the unsaved files automatically. That's useful.
if you have like 200+ repos it might take 15 mins to git pull for all of them. I had a plan at somepoint to use logstash or something to parallelise this so it'd be all able to be done concurrently and logged into a single json somewhere but I never got around to it.
#crontab -l
0 * * * * /bin/sh /Users/MyLoginNameAndNoLolYouMayNotKnowIt/code/bitbucket/updateRepos.sh
$ cat /Users/MyLoginNameAndNoLolYouMayNotKnowIt/code/bitbucket/updateRepos.sh
#!/bin/sh find /Users/MyLoginNameAndNoLolYouMayNotKnowIt/code/bitbucket/ -name .git -execdir git pull \;
I just turn on "Local History" in my NetBeans IDE which creates a new version of the file each time I save it. No need to use Ctrl-Z for that.
Not quite sure how suspending my editor and returning to the shell would help ;)
you think you just lost days of workThat really doesn't mean anything.
> I don't really see how this situation described at the readme.md could happen :-)
Start working on a big and complicated refactoring, don't commit because everything's broken and in flux, run the wrong command and lose your changes-in-flight somehow (reset the working copy, revert a file, overwrite a file incorrectly, ...).
I've been fortunate to "only" lose about 2-3 hours of work to mis-typing in git in the last year. It could have been 2 days or so if I was unlucky. For 2-3 hours of work it's maybe not worth installing this tool, but I'm definitely thinking about it because it's so much better than potentially losing 2 days.
"Commit often" doesn't work for me a lot of the time, I'd spend up spending almost as much time rebasing and patch committing as I would in dev/refactor. When you're exploring you try 5 things for every one that works, and it's not apparent til later which thing you want to keep. Committing junk every 10 minutes and then committing a rollback for most of it isn't ideal.
I've definitely wished IntelliJ's local history could work across multiple files a few times, it did let me recover from fuckups more than once but having to find and revert each file individually was not fun.
Now what?
You mean, other than backups? Including editor backups, in a separate directory.
https://en.wiktionary.org/wiki/dura is also not mentioning it.
See also https://news.ycombinator.com/item?id=29785163 - it is not so clear insult anyway.
And anyway, it would be anyway fitting for git using tool (git also has meaning as pejorative, typically male)