Git and Ruby

My company has only recently moving to Git and GitLab. Before we were using Subversion and it took a bit to get accustomed with the new workflow.

One problem was that I forgot to push the branch after I finish work on a feature. Since I wanted to be sure that I pushed all my changes I did a

git push --all 

from time to time.

Unfortunately this has a drawback! If a branch has been deleted on the server but not locally, it will be recreated. I asked my system administrator to create an hook that would prevent me to push new branches from my computer, but he told me that we were on a free plan and hooks were not supported. NB We always created the branches via the GitLab UI.

Luckily for me, Git supports hooks also on the local local machine, so they can perform checks when I commit or push code.

The are many hooks and there are many samples as well; to see them just do a

ls .git/hooks/

from inside your repository and you will see them.

The provided examples are all bash scripts (they also run on Windows) but I wanted to dust off my Ruby that I studied too many years ago. I created my pre-push hook in Ruby: it checks if I am trying to create a branch and if it so, it makes my action fail. You can find the code here.

Unfortunately, due to requests to my sysadmin we could not create the branches on GitLab anymore, and we had to do the opposite than before: create branches locally and upload them to GitLab.

My sysadmin asked me to create the branch with the same name as they were created by GitLab. This was a real nuisance, so I decided to go back to Ruby again and create a script that does it for me.

The script had to do three operations:

  1. Given an issue number, download the title of the issue from GitLab
  2. Create a valid branch name, like the one that GitLab would have generated
  3. Create the branch locally and set the upstream

For the first step I used the GitLab API provided by NARCOZ.

def download_issue_description(issue_id)

  g = Gitlab.client(
    endpoint: END_POINT,
    private_token: PRIVATE_TOKEN,
    httparty: {
      headers: { 'Cookie' => 'gitlab_canary=true' }
    }
  )

  issue = g.issue(PROJECT_ID, issue_id)

  return issue.title if issue != nil

  return nil
end

I needed to create a personal access token from my profile settings and to note down my Project ID, but it was easy. The end point is https://gitlab.com/api/v4

Once I got my issue title was easy to create a valid branch name as GitLab was doing

def convert_issue_description( issue_description )

  newDescription = issue_description.strip.downcase.gsub(/([^a-z0-9])+/, SEPARATOR)
  newDescription = newDescription.gsub(/SEPARATOR SEPARATOR+/, "")

  newDescription.chop! if newDescription.end_with?(SEPARATOR)
  newDescription = newDescription[1, newDescription.length] if newDescription.start_with?(SEPARATOR)

  return newDescription
end

To create the branch I just execute Git commands

def create_branch(issue_id, desc)
  newBranch = issue_id.to_s() + SEPARATOR + convert_issue_description(desc)

  # I create the branch
  command = "git checkout -b " + newBranch + " master"
  puts command
  system(command)


  #I set the upstream
  command2 = "git branch --set-upstream-to origin " + newBranch
  puts command2
  system(command2)
end

This really sped up my job and reduced the number of errors I could do!

The code is hosted on GitLab

The image is Gold vector created by vectorpouch – www.freepik.com

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.