Running the SilverBullet Git Plug-in with Version 2

I recently discovered SilverBullet and am just about to start using it. In the future, I plan to migrate all of my thousands of notes currently stored in Evernote to SilverBullet.

After trying it out a bit, I became completely hooked on SilverBullet. I’ve decided to go with version 2 instead of v1. I’m self-hosting it using Docker and have already created a few pages.

Now, the issue I’m facing is that the AutoSync feature of the SilverBullet Git plug-in doesn’t seem to work.

I added the following lines to the CONFIG page, then ran Plugs: Update, System: Reload, and also reloaded the page in my browser:

config.set("plugs", {
  "github:silverbulletmd/silverbullet-git/git.plug.js"
})

config.set("git", {
  autoCommitMinutes = 1,
  autoSync = true,
})

The Git: Sync command works perfectly — it commits and pushes to my GitHub repository just as I want, and changes are correctly pulled from another device. Manual operations seem to work fine.

However, judging from the Docker logs, AutoSync doesn’t appear to be running at all. In fact, no automatic push or pull actions seem to be happening.

I’m not sure whether this issue is related to changes introduced in v2, a problem with the plug-in itself, or perhaps something wrong in my configuration. But I wanted to report the issue and share my experience in hopes it may help with future improvements.

I love open-source software, and I hope to contribute and be involved in the community.
Thank you very much — I’m looking forward to what’s ahead!

I believe this functionality has been removed in v2. In the changelog:

  • You’ve entered the brave new world of SilverBullet 2.0. Welcome
  • The following features have been removed:
    • Cron hook (plug feature)

And the autocommit function in the git plug relies on a cron hook:

name: git
requiredPermissions:
  - shell
functions:
  autoCommit:
    path: git.ts:autoCommit
    env: server
    cron: "* * * * *"  <----

I haven’t seen any information about reimplementing the cron hook. There is an event dispatched called cron:secondPassed that could probably be used to implement a similar feature locally. I also so a discussion somewhere that included code to sync when leaving a page. I’ll try to find that and see if it works in v2.

Edit: This was the post I had seen. I haven’t tested it.

I wrote something using cron:secondPassed to attempt to sync every autoCommitMinutes:

-- put this in a space-lua code block
gitConfig = config.get("git", {})
autoSyncEnabled = gitConfig.autoSync or false
autoCommitMinutes = gitConfig.autoCommitMinutes or 5
print("autoSyncEnabled: ", autoSyncEnabled)
print("autoCommitMinutes: ", autoCommitMinutes)

-- This event triggers often enough that two or more subsequent 
-- dispatches can both try to sync. We can imitate cron '* * * * *'
-- by trying every minute or so. Two or more subsequent events can
-- still race if event handling has slowed down, but this is close enough.
delayBetweenAttempts = 60

if autoSyncEnabled then
  event.listen {
    name = "cron:secondPassed",
    run = function(e)
      currentTime = os.time()

      if currentTime - previousCheck > delayBetweenAttempts then
        previousCheck = currentTime
        if (currentTime - previousCommit) / 60 > autoCommitMinutes then
          print('"autoSyncing" git')
          previousCommit = os.time()
          system.invokeCommand('Git: Sync')
        end
      end
    end
  }
else
  print("Git autoSync is not enabled.")
end

It reads the git config using the standard config options:

-- in a space-lua code block in CONFIG or wherever you want
config.set {
  plugs = {
    -- Add your plugs here (https://silverbullet.md/Plugs)
    -- Then run the `Plugs: Update` command to update them
    "github:silverbulletmd/silverbullet-git/git.plug.js"
  },
  git = {
    autoCommitMinutes = 15,
    autoSync = true,
  }
}

It runs client side instead of server side, so it won’t truly attempt every autoCommitMinutes. But trying every autoCommitMinutes while a client is active seems reasonable enough.

Thanks for figuring this out. My plan was to rebuild the git plug as a space lua script. This is what I’m using now for myself:

Indeed, what this is missing is the cron aspect of it, which you are implementing with your cron:secondPassed handler. I’ll integrate that with my version and then publish it somewhere. Or if you like you can fork my version and add this to it.

3 Likes

I added to your gist: git.md · GitHub

2 Likes

@wbh Nice, I wondered how to implement cron-like functionality. This should go to docs, if not there yet (with some simplest possible example, e.g. print something every 10 seconds to logs). :slight_smile: It also looks like the git plug is somewhat obsoleted now. :+1:

2 Likes

I’m glad it was helpful. I also added a bit to my gist to skip the initial sync (skipInitialSync in the git config) because I was spamming my repo with commits when using System: Reload while testing. I will look into adding a basic cron-like example, probably to the event API page.

1 Like

FYI on using gists as the way to distribute libraries like the Git one: I’m coming around to the idea of the practice of putting these in proper git(hub) repos again. Less messy.

I still need to build easier Import support for this, but likely I’ll encourage creating repos like this one to collect this stuff: GitHub - silverbulletmd/silverbullet-libraries: Awesome SilverBullet libraries that way people can also create issues, PRs etc. Not sure if it will be better to have one repo per library or not. We’ll see.

4 Likes

I’m experiencing an issue with the git.commit function from @zef’s gist. When I run it, the function successfully stages files with git add, but the actual commit never happens.

The function prints “[lua] Committing…” at console and runs without errors, but when I check git status afterwards, the files are staged but no commit was created. The git commit -a -m command seems to be failing silently.

Has anyone else encountered this?

I am deploying SB with docker.

Checking the network call log for git.commit(), the issue is probably inside the SB docker where the shell is running, the author identity config is not set:

{
    "stderr": "Author identity unknown\n\n*** Please tell me who you are.\n\nRun\n\n  git config --global user.email \"[email protected]\"\n  git config --global user.name \"Your Name\"\n\nto set your account's default identity.\nOmit --global to set the identity only in this repository.\n\nfatal: unable to auto-detect email address (got '<masked>.(none)')\n",
    "stdout": "",
    "code": 128
}

I have set the global config on my server so when I ran inside the space folder in my server it’s working properly; but the same does not apply to the SB docker.

Just set the config at your space folder level will resolve the issue:

# Replace with your actual email and name
git config user.email "[email protected]"
git config user.name "Your Name"

Docker is probably running as some other user.

I’m having the same problem. I can git push with terminal inside the space folder on the server through SSH, but using the console inside SilverBullet only commits but not push it to the remote.
I’ve set git config at the server level for the space folder, but that doesn’t seem to fix it. Were you referring to the folder inside the docker container instead?

Yes, this is a bit of a pain. What I did myself (I’m pushing to Github) is described over here: Backup your space to Github

I was mainly resolving git commit. Didn’t try git push myself.

I think if you use volumes/ bind mount in docker (if not you should follow @zef guide) , the space folders at your server level will be available inside the docker shell environment.

So if you set your remote origin in the server level for the space folder, supposedly it should work because git will just check what’s inside the .git folder (i think so not 100% sure).

Have you set your remote origin?

You can also check the network call to see what’s happening.

Based on the @Zef version, the last space-lua script (in @Zef’s Git.md) has been modified to include an event-driven git autosync feature.

I tested it for a while, and it currently worked properly as expected: event-driven Library/Git.md

Hope this can help buddy limit the incoming and outgoing traffic on the server side :slight_smile:

PS: ❶ Event-triggered Sync is enabled by default, and does not need to be configured in CONFIG. ❷ However, the Periodic Sync is independently of this, and still needs to be configured in CONFIG. ❸ In addition, a (Periodic) Sync will be automatically triggered the moment the plug-in is updated (Ctrl + Shift + p) or the SB is initiating, if the Periodic Sync is properly configured in CONFIG.

config.set {
  git = {
    autoSync = 60 * 24, -- Periodic Sync is now only used to synchronize once at startup (with a large interval set). This seems more suitable for read-only mode (website viewers only pull once when loading, but it should be noted that each user will pull it once), while the writer only pushes through Trigger Sync.
  },
}