Today, I want to show how you can automate removing of old branches when merging child branches in a parent branch. Now, one can say this topic had already been overtaken due to the wide use of CI and services like github/bitbucket. But as the story says: “Github will help only those who help themselves.”
Let’s assume we have a project of the following structure:
To start removing branches, we need to define first what actually needs to be removed.
<p>CODE: https://gist.github.com/VladMogwai/0f3b520ca7b84f556b50c4bcde0149da.js</p>
Returns all branches names that contain current commit. If HEAD is on e, we will get the following output:
<p>CODE: https://gist.github.com/VladMogwai/02c06d38b9993082b991d515c1dad854.js</p>
To exclude the current branch, as well as a master one, from the output, let’s add the following regex:
<p>CODE: https://gist.github.com/VladMogwai/30d065dc3c5ae11eb456ff063df945cf.js</p>
If you need to exclude any more branches, ‘develop’ for example, the expression will look like:
<p>CODE: https://gist.github.com/VladMogwai/906da61330d1353aa296f61a4a5adeab.js</p>
To remove detected branches from the remote repository, we run the command:
<p>CODE: https://gist.github.com/VladMogwai/8403671fe876563c3edc4d4726333ab8.js</p>
And here’s how it will look like after being combined with the logic we already have:
<p>CODE: https://gist.github.com/VladMogwai/1af166f0ae8f865d1aeae3a0725bd799.js</p>
Now after we’ve written a code that removes a branch from a remote repository, we need to make sure that local branch copies always end up being removed too. The following instruction will help us so this:
<p>CODE: https://gist.github.com/VladMogwai/7c7ef77be856d1113acc4fdcdabbe914.js</p>
After removing all branches from a ‘remote’, this is how instruction’s output will look like:
<p>CODE: https://gist.github.com/VladMogwai/238138cf132fec641ef1c16c75d1572b.js</p>
As seen from the output, branches now have ‘gone’ status, which allows us to write a regex, find branches, and delete them.
<p>CODE: https://gist.github.com/VladMogwai/7428abde45bc5e6617dcf7be0dc6a4fa.js</p>
From combining it with the previous expression, we’ll get:
<p>CODE: https://gist.github.com/VladMogwai/8d467f419e9a17e933e3b688115f2f75.js</p>
After command execution, we’ll get the following output:
<p>CODE: https://gist.github.com/VladMogwai/3ec1be515fc7fe83de2101fff64da198.js</p>
For the sake of convenience, let’s add ‘alias’ for this command into gitconfig, by calling
<p>CODE: https://gist.github.com/VladMogwai/1fa9ea5fd8801f573f2ad2ec497286f8.js</p>
And adding the following string there:
<p>CODE: https://gist.github.com/VladMogwai/d89da263294f3b2ad749fee965887eff.js</p>
Now we can remove branches with a single command
<p>CODE: https://gist.github.com/VladMogwai/a6508abab7e7e1e51683e9edf05bbf4d.js</p>
There’s only one small problem left: no to forget to run a script that removes unnecessary branches whenever merging is done. But wait, is it a problem at all? We could just use ‘post-merge commit hook’, and that’s it!
To do this, let’s create a .git/hooks/post-merge file, and add one single command to it:
<p>CODE: https://gist.github.com/VladMogwai/71698e6cc8b7c3c58df607ed3bc941a2.js</p>
Let’s make sure that file is accessible:
<p>CODE: https://gist.github.com/VladMogwai/2d34894f237df688c75160beab4430aa.js</p>
So now, after every merge, all merged branches will be removed automatically.