-
-
Notifications
You must be signed in to change notification settings - Fork 293
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Automatic commit & push during a closing an Obsidian #13
Comments
Or even automatic pull |
if it is difficult to catch Obsidian closing, for example, then button "Push to git" could be added to the interface or to the plugin settings page. Thanks 💜 |
It is not possible to run such code on closing. You have to call the push command before you close Obsidian. |
After some research. Maybe it's still possible. |
The current api interface does not work, why we have to wait until it's fixed by the Obsdian devs. |
The api is still not fixed, but even if it would work, there's a limit of 4 seconds before Obsidian shuts down even if the plugin still pushes. I doubt that 4 seconds is enough to safely commit and push. Maybe it breaks something if it's stopped while running. |
I think the problem is, that we want to have similar instant-save-capabilities which online services such as Google Docs etc. offer - but we are using Git for this instead of directly sending messages / states / diffs. Even if Git and the repository could handle a commit every 10 keystrokes without the Obsidian UI randomly freezing or showing other artifacts or high CPU load... Even then we would generate possibly too many commits during each typing session. The larger the repository is, the more time git would need to go through all the files to check for any changes. Theoretically, one could use some Git Internals and try to synchronize git-objects only (without using commits). One could then synchronize these git-objects in real time with the server in a background process. And whenever the user closes Obsidian (or the next commit time is reached) - we only need to snychronise the last few seconds of changes and combine them into a commit. This final push will only take a short time, since most of the objects have already been synchronised previously. When looking at this stackoverflow discussion, it seems not so far fetched to do that. But most remote repositories would regularly run This is just inteded as food for thought here though 😅 |
I'm not a typescript person, but would something like this work? I think exec can live past the parent process, so that would be a way around the time limit. In a real implementation, some sort of time governor might be good to ensure this doesn't hang for some reason, but all of that can be pushed over to the child shell process. In main.ts:
|
Inspired by using Shortcuts on iOS/iPadOS, I wrote a simple script for macOS that you can save as an application and then use to launch Obsidian instead of clicking on Obsidian's application icon directly: do shell script "
open -Wa Obsidian
cd ~/path/to/your/vault && git add . && git commit -m \"insert commit message here\" && git push || true
" Paste the above into Scripteditor and then customize There is just a small cosmetic shortcoming: you will see two Obsidians in your dock, one in the place where you put the script and one to the right in the recent applications section. When you quit Obsidian, the little dot that indicates an open application will disappear under the former icon with a delay, because the script is still committing. If you have multiple vaults that you sync using Git, you can repeat the last line of the script for each repository. A similar approach could probably be taken in Linux using With the above approach, obsidian-git is still responsible for the initial pull and for periodic backups while the app is open. |
I'm tinkering with something similar to what @jgonggrijp does with Shortcuts, but for Windows, using AutoHotKey. Essentially similar, it's a separate launcher for Obsidian but it'll also wait for shut-down and then, afterwards, run the git commands. This avoids the 4 second problem mentioned earlier, with minimal overhead. I can share the AutoHotKey script if anyone's interested. Would it help to put in a feature request for Obsidian to have a "run task at shutdown time, but wait for this to finish, and then shut down" functionality? |
Please share the AutoHotKey script, @dylan-k. I'm interested! Also, I think asking for a shutdown script feature at Obsidian core is a good idea. |
I was wondering if maybe the following flow for tracking changes wouldn't be better: First we need several timers:
The separation of commit and push would help, because we could constantly keep track of changes via commits in local repo, with added benefit of clean and squashed history in remote (without the need to keep local commit history in the repo). By prompting to wait we can ensure that changes are pushed before exiting. |
@T3sT3ro As described in this comment, there are only 4 seconds before exit. I can't stop the exit process with a notification.
You want a different history for remote and local? I don't know how that should work. |
@Vinzent03 about the 4 second limit -- what I had in mind was some kind of "capture" of the exit event - instead of exiting the app, cancel it and present user with a popup, that has As for separating add, commit and push, I don't really have some strong arguments for nor against, but from experience I can say that git basically has 4 areas: Because What I currently use on my system is the following crontab run every 15 minutes. I think the flow idea works great and it would be useful to reproduce it here. It reduces the amount of commits in the repo, and each commit describes a meaningful "editing session". #!/bin/bash
# The idea is to commit only after some inactivity.
# For cron interval X, there is the period it works like so:
# The session is called a "flow" because you are "in the flow" when editing files
# | is cron interval, + is local file modification,
# C is new flow commit, a is ammend, P is push, s is pull
# f is the moment `.flow` file is generated, r is when `.flow` file is deleted
# .flow file is added to .gitignore
# |.....|+.++.|..++.|....+|.....|.....|.+...|.....| <- cron interval 15 min
# s s fC a a srP s fC srP
# ---------flow #1--------- ---flow #2--- <- one commit per flow
cd "$HOME/notes"
msg_cmd(){ # compose commit message
date +"auto sync $(cat .flow)@$HOSTNAME: %x %X"
}
CHANGES="$(/usr/bin/git status --porcelain | wc -l)"
if [[ "$CHANGES" -eq 0 ]]; then # nothing changed
/usr/bin/git pull # sync remote changes first
if [[ $? -ne 0 ]]; then # notify on merge conflict and exit
/usr/bin/notify-send Notes "Conflicting notes" -i update-high -h int:transient:1
exit 1;
fi;
if [[ -e .flow ]]; then # if there was a flow, but it became stale
/usr/bin/git push
rm .flow
/usr/bin/notify-send Notes "Flow synced" -i update-low -h int:transient:1
fi
else
/usr/bin/git add . # if changes exist - add to index
if [[ -e .flow ]]; then # if there is active flow, ammend the commit + time
/usr/bin/git commit --amend -m "$(msg_cmd)"
/usr/bin/notify-send Notes "Flow updated" -i update-medium -h int:transient:1
else # if there is no active flow, create new commit
date +%s >.flow # create a session with timestamp as session ID
/usr/bin/git commit -qm "$(msg_cmd)"
/usr/bin/notify-send Notes "New flow started" -i update-low -h int:transient:1
fi
fi |
The key of this issue is that this is not possible. I cannot delay nor cancel the exit process. Thus, it's not safe enough to either commit or push. |
If Obsidian does not support delay or cancel the exit process, can it support a command like "Commit, Push and Exit"? Then users can assign a hotkey to this command. When they need to exit Obsidian, they just press this hotkey instead of Alt+F4. This will be quite similar to delay exit. |
@a1exwang Thanks, an interesting idea. Available in new release |
Is the shortcut to "Commit, Push and Exit" implemented? I tried looking for it, or something equivalent, both in obsidian-git settings as well as in Settings > Hotkeys but couldn't find anything. @Vinzent03 Edit: Nm, I see a "create backup and close" option. |
here's a shell script that you can run as a chron job that push/pulls on Obsidian open/close: https://gist.github.com/raghavauppuluri13/c55d5a6a820d75926472089c0d842f06 |
@raghavauppuluri13 your script works flawlessly, thank you! |
I am using a linux system. so I can simply run the following to open the crontab file:
Then add the following line:
which ensures that the script gets started on reboot and any |
This is pretty good, considering I don't even need a different hotkey -- it is possible to assign Alt+F4 as the hotkey. I also added this snippet to force myself to use the hotkey:
There are still other ways to close without backing up, of course, but this is good enough. Unless you can find a way to intercept the vault closing/app exit and replace it with "backup and close". |
one of common solution for this kind of problem is that launch a detached process and do the actual work in that process. |
Maybe we can run a sync service in background, and 4 seconds is enough to send a sync message to the service. |
bump + is it not possible to block the close process? |
No, and I doubt that this will ever change. It certainly won't change on all of the different operating systems where Obsidian runs. The reason is this: when a multi-tasking OS decides that it's time for a process to end, it will usually send some kind of signal to that process saying "shut yourself down". When a process receives this signal, it is expected to save whatever data needs to be saved and then exit cleanly. If the process doesn't exit within a certain amount of time, the OS assumes that the process is "hung" and didn't receive the signal, so it will kill the process, i.e. just stop giving it any CPU time slices and remove it from memory. If this happens, any data that wasn't saved (to disk, to network, etc.) is lost. It might be nice if the OS had a mechanism where, when a process receives this signal, it could tell the OS "wait, I need more than two seconds to save everything" ... but that's not something that macOS, Linux, or ms-windows have support for. The closest I've seen is in macOS - it sends a different signal when telling a process to shut itself down because the system itself is shutting down, and there's a way for the process to say "no" and block the system from shutting down ... but this feedback channel isn't available for normal process shutdowns. |
super helpful, thanks! |
It would be very useful to be possible to turn on an option to
automatic commit & push during the closing of an Obsidian Vault.
The text was updated successfully, but these errors were encountered: