One thing I really need
to add to my Gollum install is the ability to auto sync with a remote git
repository.
In this article I am
going to go over a simple way to do that using git hooks. In the end every Gollum commits a change it
will push that change up to the remote repo.
Also, every time another repo pushes a change to the same remote repo it
will run another hook that will cause Gollum to run a git pull locally.
Git hooks and remote
repositories
First a quick lesson in
git hooks! It's been a long time since
I even fiddled with git hooks and I am by no means a master. So it's probably a good idea to set up a
test.
So as a test let me
first set up a git repo and a remote git repo to push to.
> mkdir push_test.git
> cd push_test.git
> git init .
> git config
--global user.email "you@example.com"
> git
config --global user.name "Patrick"
> echo "hello
world" > test.txt
> git add --all
> git commit -m
"First commit"
> git log -n 1
|
Quick set up of a git remote
repository
If you are reading this article I am assuming you have a
remote git repo set up and good to go.
But just in case you don't, and to help me the next time I do this, I am
going to set up a git remote repository on an Ubuntu 16.04 server I have.
First you need to make a git user (this will set the git
user default shell to git-shell to prevent logins
> sudo useradd git -m
-s /usr/bin/git-shell
|
Create a location to store your git repos. (and make the git
user the owner)
> sudo mkdir /git
> sudo chown git:git
/git
|
Now switch to the git user
> sudo su git
|
You will see that you cannot do it, you need to specify the
shell since we set the git-shell as the default.
> sudo su git -s
/bin/bash
|
That worked.
Now go make a bare repo.
> cd /git
> mkdir push_test.git
> cd push_test.git
> git init --bare
|
One last thing to set up on the git remote server, the ssh
keys!
SSH public keys need
to be added to the git users .ssh/authorized_keys file.
Generate the SSH keys (for git user on the git-test server)
> ssh-keygen -t rsa
-b 4096
|
> vi
~/.ssh/authorized_keys
|
And copy/paste the ssh key from the server (In my case my
gollum server)
Last thing I need to do is to unlock the git account. (I can't do this as the git user since it
does not have sudo access) Also I need
to set the users password
> sudo passwd git
> sudo usermod -U git
|
As a test try to ssh from your server to the git
server. (In my case the git-test server
is living at 192.168.0.142 change this to whatever address yours is using)
> ssh
git@192.168.0.142
|
The connection succeeds, but it also fails to login because
it uses the git-shell which will not allow git to login via ssh. But, it will allow it to push git changes to
it via the ssh protocols.
Now it should be ready to be pushed to from my gollum
server.
Push to the remote git server
First add the remote.
> git remote add origin
git@192.168.0.142:/git/push_test.git
|
Now push it (push the
master branch to the remote named origin)
> git push origin master
|
I prefer to set my upstream so that I do not need to
designate the remote repository when I do a push.
This command will do that.
> git push --set-upstream origin
master
> git config --global
push.default simple
|
Now If I commit a new change…
> echo "test" >>
test.txt
> git add --all
> git commit -m
"Second commit"
|
Then I can just do git push
> git push
|
Client-side git hook
Now that I have it all connected, how can I get the wiki to
auto push up to the remote repo on changes?
You can read up on git hooks at the official docs https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks
[1]
Create a post-commit hook that will run after a local commit
has been completed.
> vi .git/hooks/post-commit
|
And place the following in it.
#!/bin/bash
#Simple push to origin master
git push origin master
|
Save it and make it executable
> chmod a+x .git/hooks/post-commit
|
That should be it.
Let's run a test…
Run gollum against this folder
> cd push_test.git
> gollum
|
Now open up the website and start editing the wiki (my
server happens to be at 192.168.0.77
http://192.168.0.77:4567/
Create a few wiki pages
I made a few pages and edited them a few times.
Let me see what happened.
Let me look at the local log
> git log -n 2
|
To test let me pull the git repo anew in the /tmp directory/
> cd /tmp
> git clone git@192.168.0.142:/git/push_test.git
|
> cd push_test
> git log -n 2
|
And it did not work…
I believe the hook is good but there is an issue with how
gollum's git tool.
To prove this out let me go back to the original repo and
hand edit a file and check it in.
> cd ~/push_test.git/
> echo "new
stuff" >> test.txt
> git add --all
> git commit -m
"Added by hand"
|
Now go to the repo that was cloned in the /tmp directory and
pull it.
> cd /tmp/push_test/
> git pull
> git log -n 2
|
That worked just fine.
So the hook is fine! Gollum's
implementation of git is lacking.
Fixing Gollum's Git
I found this post on the subject https://github.com/gollum/gollum/issues/69
[2]
K00P at the bottom has a suggestion on how to fix it. I am going to try and implement that fix.
Create a config.rb file (in my simple case I am going to do
it in the repo itself … which is probably not the best place to put it)
> vi config.rb
|
And place the following in it (Replace the path with your own)
Gollum::Hook.register(:post_commit,
:hook_id) do |committer, sha1|
system('.git/hooks/post-commit')
end
|
Now start gollum, but use the --config option to load this
file.
> gollum
--config config.rb
|
Now open the wiki page and edit a page.
Check the last log in git
Now go to the repo that was cloned in the /tmp directory and
pull it.
> cd /tmp/push_test/
> git pull
> git log -n 2
|
Looks like a match to me J
Auto pulling
How do I get Gollum to auto pull from the remote repo? I will not use this often, but there are
times when I do pull down a git wiki repo and add small images to it and then
push it up.
One idea is to just put it all in a cron job and run pull
every minute see http://www.nomachetejuggling.com/2012/05/15/personal-wiki-using-github-and-gollum-on-os-x/#toc-synchronization-with-github
[3]
I am not too fond of that idea, but it does take away the
need to have a config.rb file.
My other choice is to set up a custom hook on my remote git
server that will force my gollum git to run a pull.
I am going to try that and see how successful I am J
First I need to make sure I can ssh from my git server as
the git user to my gollum server.
Login the git server and switch to the git user and obtain
the public ssh key.
> sudo su git -s
/bin/bash
> cat
~/.ssh/id_rsa.pub
|
Copy that into the ~/.ssh/authorized_keys on the gollum
server.
> vi
~/.ssh/authorized_keys
|
In the git server head over to the base of the git repo you
want to add the hook to.
> cd
/git/push_test.git/
|
Create the post-receive hook
> vi
hooks/post-receive
|
And place the following in it (tweak the user settings to
your own
#!/bin/bash
#Set user to login to gollum server as
USER="patman"
GOLLUM_ADDR="192.168.0.77"
GOLLUM_DIR="~/push_test.git"
#First check to see if the Commited SHA on the GOLLUM server and
here are a match
LOCAL_SHA=$(git rev-parse --verify HEAD)
GOLLUM_SHA=$(ssh $USER@$GOLLUM_ADDR "cd $GOLLUM_DIR; git
rev-parse --verify HEAD")
#If they do not match then GOLLUM server needs to do a pull
if [ $LOCAL_SHA != $GOLLUM_SHA ]; then
ssh $USER@$GOLLUM_ADDR
"cd $GOLLUM_DIR; git pull origin master"
fi
|
Make it executable
> chmod a+x
hooks/post-receive
|
Now in theory when a change is made on gollum and commited
it will auto push the code to the remote repo which will then run this hook
upon completion. This hook will run but
nothing should be done because the local SHA and SHA on the gollum server will
be equal.
But if I push a change up from another location to the
remote repo it should force gollum to pull down the changes.
Let's see if it works. ..
Restart Gollum
> gollum
--config config.rb
|
First make a change in Gollum from the wiki page. Just to make sure I did not break anything.
Checking the local git repo and remote git repo
> git log -n 1
|
Both are identical so the auto-pushing is working.
Now to test the auto pulling…
Go to the cloned repo in the /tmp directory and get a fresh
pull
> cd /tmp/push_test
> git pull
|
Make a change to the Home.md file
> vi Home.md
|
Add some text and save it. Add it, commit it and push it up.
> git add
--all
> git commit -m
"Non-gollum added"
> git push
|
Now did that work?
Wahoo it worked!!
References
[1] Git hooks
[2] git hooks are not firing
when using gollum web interface
[3] Personal Wiki using GitHub
and Gollum on OS X
http://www.nomachetejuggling.com/2012/05/15/personal-wiki-using-github-and-gollum-on-os-x/#toc-synchronization-with-github
Accessed 4/2017
Accessed 4/2017
This was super helpful! Thank you so much for documenting this process so clearly, especially for including your full process.
ReplyDeleteI set up a Gollum instance at work for some internal documentation, and this helped me set up an automatic backup of it to a private Bitbucket repository.
I linked to this article from an article in my Gollum instance, but it's on a private server.
All the best to you!