A simple pastebin/gist-like service (server side). The underlying database is git. Syncs automatically with GitHub or any other git server.
It allows
- Creating new (unamed) files and saving them on the server
- A file revision is immutable. Once written to the server it cannot be changed.
- A file revision can have history. It is an edit of another revision.
- Sharing the files by publishing a "revision id" that identifies that revision of that file
- Editing an existing file revision according to its revision id (this will create a new file with the original text and original history)
- Browsing the change history of a file, and branching it to a new file
To deploy in a Docker container, first build the docker image:
sudo docker build -t snippetbin ./
Then run it with environemnt variables like this:
sudo docker run -d --restart unless-stopped --name snippetbin -p 443:443 \
-v /var/snippetbin/data:/snippetbin_data \
-e "SNIPPETBIN_PORT=443" \
-e "SNIPPETBIN_DEPLOY_KEY=$(cat /var/snippetbin/deploy_key)" \
-e "SNIPPETBIN_REMOTE_REPO=my_snippetbin_data.git" \
-e "SNIPPETBIN_DATA_DIR=/snippetbin_data" \
-e "SNIPPETBIN_SSL_KEY=$(cat /var/snippetbin/ssl.key)" \
-e "SNIPPETBIN_SSL_CERT=$(cat /var/snippetbin/ssl.cer)" \
snippetbin npm start
This example would start SnippetBin in Docker and start HTTPS server on port 443,
with the specified GitHub deploy key (ssh) and certificates (ssl).
The data directory would be mounted to /var/snippetbin/data
on the host.
It will look for the deploy_key and ssl keys under /var/snippetbin/
on the host.
It will use my_snippetbin_data.git repo on as backing database.
https://snippet-bin.herokuapp.com
Input:
- revision key
Output:
- file text
- revision history (list of revision keys)
Input:
- file text
- original revision key (optional)
Output:
- new revision key
- User provides new text, and asks to save the file
- Client calls SAVE-FILE with user text.
- Client publishes revision key in a URL
- Client saves revision key. It will be used when the user edits the file
- User continues to edit an existing file, and asks to save the file. (or file automatially saved)
- Client remembers the revision key for the file the user is editing
- Client calls SAVE-FILE with user text and the revision key
- User provides revision key (through URL, or by selecting it from revision history)
- Client calls LOAD-FILE with the revision key
- Client displays file text to the user, and allows editing it.
- Client displays the user the revision history, in case the user wants to go back to historic revision of the file
- Client saves revision key. It will be used when the user saves his edits of the file
- Underlying database is git.
- Revision key is a commit hash
- Revision history is the log of a given commit hash
- Each commit will contain a singe file
- When saving a file
- A new file without "original revision key" will be named by a unique ID and commited.
- An existing file with commit ID will be branched from the original revision ID.
NOTE: each commit must have a parent, otherwise git diff-tree
will not work correctly. So don't start with empty repo!
Get file text according to revision key. Revision key is actually the commit ID, and each commit has only one file
Inputs:
revision_key
Outputs:
file_text
revision_history
file_hash=$(git diff-tree --no-commit-id "${revision_key}" | cut -d ' ' -f 4)
file_text=$(git cat-file -p "${file_hash}")
file_name=$(git diff-tree --no-commit-id --name-only "${revision_key}")
revision_history=($(git rev-list "${revision_key}" -- "${file_name}"))
Inputs:
file_text
- optional
original_revision_key
commit_msg
Outputs:
revision_key
if [ -z "$original_revision_key" ]
then
file_name=$(uuidgen)
git checkout master
else
file_name=$(git diff-tree --no-commit-id --name-only -r "$original_revision_key")
git checkout -B branch_$(uuidgen) "$original_revision_key"
fi
echo "$file_text" > "$file_name"
git add "$file_name"
git commit -am "$commit_msg"
revision_key=$(git rev-parse HEAD)
- Change SAVE-FILE implementation to use git plumbing commands
- Prevent checking out, no need to update all files locally when only one is used simultaneously