Q:

How to change the contents of a commit using git server side hooks with gitlab

I have installed gitlab (manually) at ubuntu 12.04.
There are some repositories that contain PSD (Adobe photoshop files).
What we hope to achieve is that whenever someone is pushing a commit to the gitlab server, it will automatically: 

Convert PSD to PNG
Move to PSD to dropbox (or other cloud storage)
Remove PSD from the commit
Add the PNG to the commit

Note: Step 2 is irrelevant to this question.
Anyway, we have managed to download tools to convert PSD to PNG which involves installing Ruby, some Ruby Gems, and PSD.rb (Google PSD.rb if anyone is interested) 
The problem is we do not wish to manage the installations (Ruby, gems, and etc.) on client side as we assume it will be hard for us to maintain the installations on a number of windows, mac, and linux machines.
So what we are hoping to achieve is that the above will be executed in server side hooks when someone do a git push and there are PSD files in the commit.
We have tried to do that in pre-receive hook but we can't manage to modify the contents of the commit (e.g. remove PSD from commit, Add new file - PNG to the commit)
Is there any other way to do the above on server side? Or there are other methods we can explore?

A:

You cannot modify a commit.
You can reject a commit, and having done so, you can make a new and different commit based on what you received.
That is, you take what you received, save it elsewhere, reject the commit, and then take the saved stuff and make your changes and make a new commit out of it.  To the user who attempted to push something, it looks like their commit was rejected, and then someone else (who is very fast at typing) did all the same work they did but then cleaned it up and committed a slightly different version while they were reading the "rejected" message.
Note that I am not particularly recommending this idea, nor going to write you code to achieve it, but it should work just fine.
You can also use a different two-step method, where there are two different servers involved:

server "pure" delivers only PNG contents, and does not take pushes from users
server "converter" takes pushes from users, accepts them (no rejection here), then cleans them up and pushes the cleaned-up version to "pure"

Users thus read items from "pure", write stuff, push it to "converter", and then read back from "pure" to get the updated (different) commits and discard their "unclean", un-converted commits.
This is exactly the same process as the first system, except that it's more obvious to everyone how it works, and users must know how to fetch from "pure" and push to "converter".  In the first system, a single git repository and machine acts as both "pure" (when delivering cleaned-up stuff) and "converter" (when receiving and secretly saving, but then rejecting, a push).

