Can pre or post receive hook add a tag in addition to the operations in the commit?

Joe Anakata November 28, 2013

We are looking at migrating from gitolite to stash. Some percentage of our tech leads are strong believers that source control should never lose history (i.e. no git-style "revisionist" history allowed). For those projects we currently have gitolite hooks which automatically make a tag of any branch that is being deleted, especially if it has not been merged. Is this possible with Stash?

If we do this from a script-based hook, will it cause any consistency problems with the database?

I've also looked at the Java hook API (which would be more ideal because the hooks can be configured through the GUI) and am not sure if it's possible with that.

This link: https://developer.atlassian.com/static/javadoc/stash/2.9.4/spi/reference/com/atlassian/stash/hook/repository/PreReceiveRepositoryHook.html indicates that we'll get a RepositoryContext https://developer.atlassian.com/static/javadoc/stash/2.9.4/spi/reference/com/atlassian/stash/hook/repository/RepositoryHookContext.html in our hook.

getRepository() can be called on RepositoryHookContext, but there is no javadoc for that.

We'll also get a Collection<RefChange> as an argument. There's also no Javadoc for RefChange, though I can surmise what sort of methods it would have. But also it's unclear if the Collection is mutable, or even if it is, whether the resulting modified Collection would actually be used by stash to finish the repository operation.

2 answers

1 accepted

1 vote
Answer accepted
cofarrell
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 30, 2013

Hi Joe,

Writing a Java hook is definitely possible with what you have in mind. We try to rely on Git as much as possible for keeping our data consistant, so you don't have to worry too much about the database in this case.

Have you seen the developer docs? We have a page on how to write one, and this is definitely the best place to start (and the examples in particular).

https://developer.atlassian.com/stash/docs/latest/how-tos/repository-hooks.html

While I don't think it will answer your questions, the Repository/RefChange classes aren't 'linked' in that javadoc because they were generated from a different Maven module. You can find the rest under 'api' (instead of 'spi'):

https://developer.atlassian.com/static/javadoc/stash/latest/api/reference/com/atlassian/stash/repository/RefChange.html

The collection may or may not be mutable (thanks to Java), but we certainly don't respect any modifications. Instead you would want to be using our Git API to create your backup tags. Unfortunately we don't (yet) have a way to create a tag nicely, so you would have to call directly into Git. Here is an example:

https://bitbucket.org/atlassianlabs/stash-filesize-hook-plugin/src/b520fe77a2a5/src/main/java/com/atlassian/stash/plugin/filesize/FilesizeHook.java#cl-96

If you get stuck let us know. It should be a relatively trivial plugin to write.

I should add at this point that if I were implementing this 'feature' I would personally not use tags. In pariticular the tags are going to clutter up your local repositories. So if someone deletes a branch, of which most people wouldn't even have checked out, when they fetch next a new tag will be created locally each time (and if you delete it the next fetch will bring it back). You would be better off using (different) branches because at least Git will keep them remote. One suggestion might be to just use a raw ref (such as 'refs/backup/*'). They would still be accessible for people who know what they're doing ('git ls-remote' and 'git fetch origin refs/backup/foo:backup/foo'), but they won't be visible under normal circumstances.

We do something like that for our currently open pull requests, so that you can see the 'merge' and 'from' refs (useful when the source is a fork). In addition we use the Git reflog to ensure that _every_ commit that has ever been on a pull request is kept, mostly so we can still show the diff comments. If you don't care about users being able to fetch these old branches (easily) I would highly recommend using the reflog instead of refs as you will find your fetch and clone operations getting slower over time as the number of refs in your repository increases infinitely (we saw this with our pull request refs which is why in 2.9 we only 'publish' the open ones instead of all of them). One alternative would be to have a 'backup' repository where you keep the deleted branches to avoid the master repository being affected.

You might be interested in this Stash feature request:

https://jira.atlassian.com/browse/STASH-3994

I hope that helps.

Charles

0 votes
Joe December 5, 2013

Thanks for the information!

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events