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

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

This widget could not be displayed.

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

This widget could not be displayed.

Thanks for the information!

Suggest an answer

Log in or Sign up to answer
Atlassian Summit 2018

Meet the community IRL

Atlassian Summit is an excellent opportunity for in-person support, training, and networking.

Learn more
Community showcase
Posted Wednesday in Teamwork

What teamwork quotes inspire you?

Hey everyone! My name is Natalie and I'm an editor of the Atlassian Blog and I've got a question for you: What's your favorite quote about teamwork?  We've compiled a list here, along with...

147 views 16 7
Join discussion

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you