Friday, January 6, 2017

Git branching model

It recently came to my mind to design a Git branching model as I was willing to implement CI & CD in the project. I wanted this model to work under a specific release cycle:

dev -> release-candidate(staging) -> release

I had some initial thoughts on how to approach the subject but I've also considered having a look online to see what other people have written about the subject. I found two articles:
Considering these two articles, and having in mind that the 'master' branch should be the almighty development branch, I took the second approach.

For this I went out in testing on how exactly everything should fall into place, and more exactly:

  • how code should move from one branch to another
  • how a single commit can be moved from one branch to another in case of a hot-fix

Merging code from one branch to another

Branching direction is always going to be: master -> staging -> release. This means that you will always have to merge 'staging' into 'release' before merging 'master' into 'staging' since you don't want to override the middle branch before you get a chance to merge it

Now that we know the process(theory) let's see how we will actually handle it(the engineering part):
  • Create a new branch. I named it 'merge-staging-release' and called it the intermediate branch as it merges 'staging' into 'release'. It should be created from 'release'!
  • Merge 'staging' into 'merge-staging-release' by fully committing everything
  • Create a pull request from 'merge-staging-release' into 'release' and commit with squash. You will have no conflicts as you've eliminated any possible ones at the previous step.
This three steps will give you a smooth merge of the two branches with a linear commit history because of the PR + commit with squash(you can usually do these by using GitHub but many other providers support it). Beware that without a PR, a merge commit will be created instead, which breaks the linear commit history.

Follow the above steps for merging 'master' into 'staging'.

Move of a single commit from one branch to a another

Same principles apply here as described above. Single difference being that instead of merging the whole branch, you cherry-pick the commit you want to move into the intermediate branch.

Notes

You will notice that the two branches 'release-candidate(staging)' and 'release' will appear as being behind 'master', that is absolutely correct and fine since we are always merging using a PR into them but never merging back. We don't need to merge back since the code is already in there.

What you could do from time to time in theory, is to delete 'staging' and 'release' at merge time and just branch them off master, targeting the right commit ofc(careful with the cherry-pick ones). I call this branching maintenance.

Sunday, July 10, 2016

Split and move a file using git while preserving history

Everyone is using Git these days. A very well known use of Git is taking place at GitHub.

On a day to day basis, people tend to push commits to different branches and with these commits, history is being built up. This history can be used to understand certain bits of code that have been modified by you or someone else in a certain user story. It can help very much when trying to get some context about that portion of the code.
It can also be used to blame someone when they've did mistakes, but that's just bad ]:)

Given the above, some projects require, all should require, to preserve history on every action that can be performed on Git.

Some of the actions are:

  1. Move
  2. Move & edit
  3. Split a file into multiple files(usually two)

Move

Moving a file from a location to another is easy as copy-pasting. Git is able to track these changes without any human intervention.


Move & edit

This is very similar with moving a file, the only difference is that you can also rename the file and also edit its contents. This action can also be tracked by Git automatically.

Split a file into multiple files(usually two)

Although this might seem like a Move & edit, it is much more interesting.
Splitting a file means that its contents should be present in both places, if splitted in two files, at the same time. This action cannot be tracked by Git automatically and it needs a little more human intervention. Quite a little more.

The idea behind this solution is to create a new branch and then move the same file in both branches. Do be careful to move them in different places or different names. After this, merge the new branch into 'master', which is the branch from which you've created the new branch.

You will have to use the following merge command while having the 'master' branch active:

git merge --no-ff 'new_branch'

The merge process will give you three conflicts. You'll have to keep both files from each branch and delete the file that was moved from both branches.

This action will preserve the history on both files.


Full process description can be found on GitHub


Next steps:

  • Split and move a file using TFS while preserving history


Related posts:

Monday, September 21, 2015

Angular modal directive with one-way-binding to object

Being new in AngularJS I wanted to see how can I easily build a Modal window with this awesome framework everyone's been talking about.

Well, one way to do it was using the angular-ui bootstrap which was pretty nice for a first shot, but I didn't like having so much in the controller.

Another problem that I faced was when modifying something in the Modal window, it was immediately reflected back on my original object. This was because a two-way binding was set between the two. This is easily fixed by using angular copy.

Then I started looking into how I could move all this code inside a directive so that everything can be re-used. I managed that, but the angular copy didn't go away.

Having to angular copy everything wasn't really something I did like so much.

I've started looking into the angular code and found that with some little changes I could add a whole new operator besides @, =, &; one that could do exactly what I need it to do: one-way-binding to an object.

I've submitted the code on GitHub and the guys were very helpful in sharing some of their ideas on the matter.(if you wonder why the CI build failed, well, I implemented and tested everything on v1.2.16 and ported the code to the current version and it seemed like I miss typed something in the regex expression. I wasn't about to commit that right away as much as I was looking for some input on the idea)

Based on that input I've come up with a whole new approach to the problem. You can check it up on plnkr.co where a functional example is provided.

As you can see in the example, in the index.html file, I'm using two directives, one named modal that will handle the Modal window and it can be used globally so we don't need to write the same code all over again, and the second directive that handles the content itself, which can be quite anything.

This has been taken and modified from a stack overflow answer in which S Hasan was so helpful to also provide a working example.

If you are wondering why the on-hide function looks like that

it is because I didn't want to pollute the controller with unnecessary code. This is the same as well for all other places I've used this approach.

Now if we were to refer to:

The one-way-bind-person is a naming convention based on one-way-bind- and entity name which we want to one-way bind into the directive.

The on-save is going to be the function that gets triggered when the OK button is clicked and mainly the save is happening and we can use as below:


The onSave function is called in order to return the function vm.savePerson that was passed in so that it can be called with the person parameter.

The person parameter is an object on the directive's scope which is added in the directive's link function:

This is also the place where the one-way binding happens. The parentValueWatch function returns the reference to the parent value, vm.selectedPerson, and when that changes, the onParentValueChange function is going to copy the contents of the vm.selectedPerson over to the directive's scope object person .

I am watching for a reference change only(if you need to watch for the properties of an object or if you pass in an array, then use $watchCollection)


Post references:
Next steps:
  • Would be nice to have an extension point in AngularJS in which we could define our own operators so that less and more organized code could be written.

Thursday, September 10, 2015

Shortest path and back

This Stack Overflow question reminded me of a very interesting problem, whose solution is difficult to find online (in fact I can no longer find it mentioned, though I might be forgetting the exact terminology).

The problem is this:

Given a graph, find the shortest path from a source s to a destination d and back to s. We will call this the shortest path and back problem, or the shortest round trip problem.

A naive algorithm is to simply use Dijkstra's algorithm, or any shortest path algorithm, to find a shortest path from s to t, remove its edges from the graph, then find a return path in the new graph. We can easily find examples for which this fails though.

The correct algorithm involves solving the minimum cost maximum flow problem. This is solved quite easily with the Edmonds-Karp algorithm, where the Breadth-First search used to find the shortest augmenting paths at each step is replaced with the Bellman-Ford algorithm.

I'll leave the details as an exercise, but give an algorithm that is easier to understand if you're not too familiar with flow networks. You can use this algorithm to figure out the flow solution, since the two are actually equivalent.

It goes like this (also available on the SO link):




  • Find a shortest path s -> d with any algorithm that can do this (Dijkstra if no negative costs, Bellman-Ford otherwise);
  • Replace the edges of this shortest path with directed arcs directed from towards s. For example, if your shortest path is s -> x -> y -> z -> d, replace the edge (s, x) with the directed arc x -> s(x, y) with the directed arc y -> x etc.
    Also negate the costs of these arcs. For example, if 
    (x, y) had cost c, the directed arc y -> x will have cost -c;
  • Find a shortest path from s to d in this new graph. You'll have to use an algorithm that works with negative edges now;
  • Remove the edges that appear in both of the shortest paths. What you're left with is the cycle you're after.


  • As an example, consider the following graph. 



    The first shortest we find is 1 -> 2 -> 3 -> 4, of cost 12. We transform our graph to:



    Notice the negated costs. We then find another shortest path in this new graph, which can only be 1 -> 3 -> 2 -> 4, of cost 14.

    We have used the edge (2, 3) in both shortest paths, so we ignore it and draw our solution shortest path and back:



    Which has total cost 26. Notice that if we had applied the naive algorithm, we would have selected 1 -> 4 as the second path, which would have led to a cost of 28.

    You can also solve this problem on UVA, where you can practice your implementation of the algorithm.

    Sunday, August 16, 2015

    Installing OpenBLAS for Theano on Windows

    Once more, this proved to be quite difficult to do on Windows, so I'll explain how I finally got it to work. I'll assume you've read the previous post about the Theano installation and that you have mingw (64 bits) installed. The order in which you do these steps shouldn't really matter, but just in case, you can follow my order.

    First, you need to download Open BLAS. Get the one called:

    OpenBLAS-v0.2.14-Win64-int32.zip (I'm not sure if this also works with the -int64 version)

    Next, make a folder C:\openblas. I don't think it must have this exact name, but it must not contain any spaces, so keep it simple.

    Now, add this to your .theanorc file

    Make sure you type it exactly like that, with the -L and everything.

    Next, from the OpenBLAS zip you downloaded, extract the libopenblas.dll file from the bin folder and the libopenblas.a file from the lib folder to the openblas folder you created. I'm not sure if you need both or not, the dll might be enough, but I just copied both.

    Finally, you also need to make the dependencies of this library available. I'm sure there's a better way to do this, but what I did was copy everything from C:\Program Files\mingw-w64\x86_64-5.1.0-posix-seh-rt_v4-rev0\mingw64\x86_64-w64-mingw32\lib (where I installed my mingw 64 bits) to the openblas folder I created. I guess you could also add this to your system Path, but that's arguably even uglier.

    This did it for me. Please comment if you have any questions or suggestions on how to simplify this process.

    Saturday, August 8, 2015

    Installing Theano on Windows 10, 64 bits, Python 3.4 64 bits

    Unfortunately, there seems to be little information regarding the installation of Theano on Windows systems. You can do it by searching on Google, but everything is spread out across different blogs, forums and groups. I'm going to try to compile this information in a single place. Hopefully, I'm not forgetting anything, but if I am, please leave a comment.

    You will need numpy and scipy installed. These are easy enough to install on Windows, so I won't get into those details. I also assume that you haven't installed Python through a package like Anaconda.

    First of all, run pip:


    You can also update it from github to have the latest additions:



    Now, the first thing I had to do was fix the problem described here. The fix involves copying the file python34.dll from C:\Windows\system32 to a temp folder and then running the following commands in a cmd window open in that temp folder (shift+right click in Explorer to open a cmd window in the folder you're in):


    Then, copy the generated libpython34.a file to your system32 folder.

    Next, you need to install a 64 bit MinGW. Add this to your System Path variable. It should look similar to this:


    Next, you should create a file named .theanorc in C:\Users\<your username>. This is created by writing .theanorc. (notice the dot at the end) in the rename textbox in Explorer. If you don't add the dot at the end, you'll get an error. You'll want the following in this file:



    Notice that you need Visual Studio 2013 for this. I tried using 2015, but that didn't work. It might work in future versions, but it didn't for me.

    As a final step (although you really could have done this at any point), you should install cuDNN. Google for it, the link might change so I'm not going to post it.

    To test that everything works, open IDLE or ipython and type import theano. You should get an output similar to this:



    It might take a while for each output to show up, but as long as there are no erros, you should be fine.