Pages

Showing posts with label nus. Show all posts
Showing posts with label nus. Show all posts

Sunday, March 20, 2016

Git vs Mercurial workflow: History, Commit, and Branching

This is going to be another Git vs Mercurial post, which is already widely available on the cyberspace (this, this, this… I can go on) but I am writing another one nevertheless because I feel that many of such posts are written with so much hatred (especially those that is in favour of Git, unfortunately). So this post is going to be one of those Git vs Hg post where the author is in favour of Git but not trying to bash Mercurial (too hard, hopefully). Also, I am going to focus on the similarity and difference in workflow instead of functionalities, though differences in workflow will inevitably also bring about some differences in features into the discussion, but I will try to minimize it.
Note: This post assumes some basic knowledge of Git and Mercurial commands.

Attitude towards commit/changeset history

In Mercurial, history are “sacred” and not to be manipulated. The only command that a user can do out-of-the-box that can edit history is only hg revert, which only removes the last changeset. To manipulate further down the history, Mercurial extensions are available, but they are tedious to use and confusing at best (speaking from my experience using Mercurial on a project 2 years ago). For Git users like myself, this is a huge annoyance as we are used to “fixing” history to make it look nicer and more easily traceable in the future.
Git, on the other hand, allows users to manipulate commit history to their hearts’ content. In fact, it seems to be encouraged, evident from how easy it is to do so (git rebase, git rebase -i, git push -f, and many other relatively short commands that changes history). This allows the creation of a better-looking, more linear commit history. However, inexperienced user may break the entire repo with it. Luckily, Git keeps track of everything and one can go back to the exact state before the accident happened (provided it didn’t happen more than a month ago; plenty of time to realize something bad has happened, if you ask me).

Commit workflow

In Git, there are 4 states a file can be in; untracked, unstaged, staged, and committed. To move a file (or more precisely, a change/modification) from untracked or unstaged to the staged state, use git addand to move to the committed stage, use git commit.
In comparison, in Mercurial there are only 3 states; untracked, uncommitted and committed. To move a file from untracked to uncommitted, use hg add and to commit use hg commit.
The difference here is that in Git, the user can choose not to commit all changes in the working directory (using git add <filename> or git add --patch, for example). This is useful to make a commit atomic (which is part of Git’s or any version control system’s best practices), or if you have finished work in some files but not in others. In contrast, in Mercurial, there is no staging state and hg commitautomatically commits all changes in the working directory. If you came from Git background like myself, you will find yourself repeatedly committing unfinished work, and what’s worse, it is difficult to fix the messy history due to that mistake! That was the pain I personally went through in the Mercurial project I worked on 2 years ago.
There are Mercurial extension that mimics this Git behavior, but I have not used it personally so I cannot comment on it. However, from what I have found on the Internet, it seems to be a decent replacement for users coming from Git background using Mercurial.

Branching

In Git, there is only one way to branch (though there are a few commands to create a new branch but that’s beside the point). Any divergence in commit history is a branch, and the name of the branch is namespaced according to which repository the branch originates from.
For example, if I have a branch called test which tracks a remote branch with the same name, if at some point in time my local branch and the remote branch diverges, when it is being merged, the remote one will be called remote/test. There is no other “branching” method.
In Mercurial, there are at least 3 ways of branching.
The first one is a clone-branch. This seems to be the initially-intended branching workflow of Mercurial, evident from the “local-cloning-optimization” feature they have called “hardlink” which makes cloning from a local repo faster. This, however, is not a feasible branching workflow for certain types of projects where dependencies need to be downloaded separately (through npm or pip, for example) for each repo.
The second branching workflow that Mercurial supports is called named-branch. It is quite similar to Git branch in that one can update (or checkout in Git terminology) to the latest commit on that branch. In Mercurial, however, named-branch is not a light-weight pointer to a HEAD just like in Git, but is something that is included in a changeset’s (or commit, in Git terminology) meta-data. There are some implications that people from Git’s world don’t really like (such as cluttering the revision history with short-lived branches and needing to “close” a branch with an extranous commit). On the other hand, it could be useful when tracing the history. But then again I have worked with Git for quite a while and I have never encountered a problem where I need to know the name of the branch a commit was from, so the usefulness is questionable.
The last branching workflow that Mercurial has is bookmarks. This is (claimed to be) the Git-branching equivalent in Mercurial. However, having used it in one of my projects 2 years ago, I find that they are not quite the same. In fact, I find that Mercurial’s named branch is more similar to Git branch than Mercurial bookmark is simiar to Git branch. In Git, you are always working on a branch, so whenever you commit, you commit to a branch and other people who pull your work knows that your commit belong to a certain branch. In contrast, you are not always on a bookmark in Mercurial, and thus people may accidentally committed when he is not on a bookmark, requiring the user to manually move thebookmark to the intended changeset. Also, when sending a pull request, the name of the bookmark is not shown. Instead, the hash of the changeset is written as the “branch name”. This makes me doubt the claim that bookmark is really the Mercurial equivalent of Git branch.
Arguably, there is another Mercurial branching workflow, which is simply not to do anything about it. If there is a divergence from a certain changeset, simply don’t do anything about it. Users can refer to a “branch” by the hash or revision number of the tip of the “branch” he/she intends to work on. This is good for quick fixes, but is not suitable for development branch as it will be difficult to keep track which “branch” is doing what. I am unsure if it is one of the intended way to use Mercurial.
Conclusion on Branching
In my opinion, Git’s branch workflow is better, as it is more consistent (i.e. there is only one way to do it). If I were to use Mercurial, though, I would probably use the named-branch workflow as it is much more manageable than all the other Mercurial branch workflow.
One may argue that Git also has some divergence in terms of branch workflow, namely "to merge or torebase". In my opinion, it is actually what makes Git great; you have the option whether to preserve history as it is or to make a cleaner, nice-looking history. In contrast, Mercurial’s different branch workflows are not really “options” but rather inconsistency on Mercurial’s default development workflow. I mean, I can’t really think of the benefit of using the clone-branch workflow, or bookmark-branch workflow over any of the other options. But then again, maybe I have not used Mercurial enough to discover the different benefits and disadvantage of the different ways of branching in Mercurial.
Just to reiterate, I wrote a comparison of two of the most popular distributed version control systems in terms of their attitudes towards history, commit workflow, and branching. I found that Git’s way of doing things to be better than that of Mercurial’s because of the flexibility and consistency that Git provides.
Feel free to point out any mistakes in my post. I have not used Mercurial for quite a while so probably some information is outdated, but I did some research before posting this so it should not be too outdated.
Other references not linked on the post itself:

Tuesday, February 16, 2016

FBOA Module: Technical Expertise - Git workflow

As part of the CS3281/2 module requirement I am currently taking in NUS, I have to establish myself as an expert in a topic/field/technology of my choice. Because version control systems are going to stay, and Git is currently (arguably) the most popular version control systems out there, and I have had some experience in it, and I have friends who are good at it (I have one too many and's), it is just natural that I choose Git to fulfil that requirement. This is going to be the first of the series of Git tips and tricks that I will post in this blog, so stay tuned!

Officially, my tech expertise is "Git workflow" because if I declare as just "Git", apparently I am expected to know Git inside out or something. Nevertheless, my Git-related blogposts will not be limited to just Git workflow, but also Git tips and tricks in general.

Some topics that I plan to write about in the next 1-2 months (which is basically the rest of the semester):

1. Git workflow best practices
2. Git rebase + push --force safely
3. Git rebase vs merge, and what is happening in the background

To get the ball rolling, here's a neat trick I got from @rauchg's Retweet on Facebook if you need to find the first commit where a given string first appeared in the source code.

git log --source --all -S <string>
What it returns is basically a list of all commits that contains the string you input as changes (both as addition and deletion). The first  commit where it appears is of course, the one at the bottom of the list. If you only need the commit's hash, you can shorten the output by adding the --one-line option to the command. Also, if you want a string longer than one word, you can put the string within quotation marks.

If you want to know what each option actually does, you can refer to git-log documentation page.

That is all for now. Stay tuned for more Git workflow goodness! Happy coding!

Saturday, January 23, 2016

The Long Overdue Update: FBOA and Webpack

Hi everyone! Seems like I have only been updating this blog for once a year, huh? Sorry about that; nothing much happened in my life that can be written in this blog anyway. Just to get you all up to speed, I went for an exchange to Tsinghua University in China, which explains why I did not update the blog. I know, using VPN to access blogspot is like just a few clicks difference but then again, as I wrote earlier, nothing particularly significant from what I have been learning that can be put in this blog. During my semester there, I tried to redo an Android Development tutorial, this time from udacity. I also took a module in computer networks though if anything, what I learn is how to make a really fast (but not necessarily scalable) C++ programme instead of anything about computer networks itself.

This coming semester would be totally different. I am enrolled in the Facebook Open Academy (FBOA) programme via NUS under the module code CS3281/2, Thematic Systems Project. If you are curious, I will be working on the open source project Socket.IO. One of the grading aspects of the module is to write a blog post about my progress in the open source project I am working on. Because I am too lazy to create a new one, so I decided to just use this blog. Who knows, this might get the ball rolling for more frequent updates to come!

... And this post is going to be the first of those more frequent updates. My team is assigned to do migration from the tools currently being used by the project to (supposedly, debatable-y) better tools. For example, I am assigned to migrate from using browserify to webpack as the bundling tool. I thought it should not be too difficult (after all, it is our first task given by @rauchg (one of the guys behind socket.io) (I am using too many brackets here)). I guess it is not difficult if you are familiar with web development, but I am not (I should have, but no) so it took me one whole day to figure out how to do it, and I am not even sure if I am doing it correctly.

Learning new tools is never easy. The initial learning curve is almost always very steep, though fortunately it will only get easier over time. Webpack is no exception. I tried reading the Getting Started tutorial the devs provided but I still have no idea how it will fit into the project I am working on. Apparently previously socket.io uses browserify's node.js API and I did not know there is such a thing so I have been trying to integrate the webpack into socket.io's Makefile to no avail.... I thought the 2 tools are very different in terms of how it is being set up. But as it turned out, webpack also has its own node.js API, which I finally found somewhere in the docs. I tried to tweak the test initialization js files and finally managed to make the test runs and passes (yay!). I will probably push and send a pull request tomorrow to let my teammates check it first. After all, I should not be embarrassing NUS by sending some crappy PR, should I?

Sorry if this post is rather confusing or hard to read. It is 3 am in the morning and I just managed to integrate webpack into the project like literally 20 minutes after one whole day of googling so I do not want to have anything to do with it again for the next few hours and wrote this just for my own reference. Anyway, here's to more frequent and higher quality updates in the future!

Friday, May 22, 2015

NUS Module Review: Year 2 Semester 2

Hi everyone! Sorry for not updating this blog more often (in fact it feels like it is never updated at all). Anyway, I finally gathered enough will to post a module review of modules I have taken in NUS. For clarity and organization purpose, I will divide the posts per semester. So here goes the last semester's module review!

CS2102 Database Systems
Lecturer: Stephane Bressan and Zhao Jin

This module is not very interesting, but it is quite useful. You will learn how to CREATE, ALTER, DROP tables, SELECT, UPDATE, and DELETE entries, and some simple joins through the WHERE clause (equality of columns). You will also learn a bit about tuple and relational calculus, relational algebra, functional dependencies, and normalizations. The topics I wrote above is not covered in depth to be useful in the real world, but I guess it gives you quite a good overview of what to expect in higher level database modules.

I mentioned that the module is useful because you get to develop a simple web application as the term project. The project's default configuration is to use vanilla PHP, but the lecturers give us freedom to choose other web framework. Of course, we have to write the SQL queries by hand (instead of relying on ORM like what most web frameworks offer). I used Django (as a friend of mine in the group is highly proficient in it), overriding all ORM methods to write our own queries, but we use Django admin for managing the database (which is the most difficult part if you use the default project configuration, I believe).  Luckily the grader did not say a word about it (or maybe he was not aware that we used it). Thanks to this project, I am not too clueless in my current internship, which is on web development.

CS2105 Introduction to Computer Networks

Lecturer: Zhou Lifeng

This module turned out to be very interesting (in my opinion, at least). We were taught the 5 layers of computer network protocol (Application, Transport, Network, Link, Physical, omitting Session and Presentation layers for some reason). There were 3 term assignments. The first one was to create a simple data transfer protocol on top of a reliable network. The second one was the most important one: to create a reliable data transfer protocol on top of an unreliable network. The last one was just to code out a simple encrypted network protocol using public key encryption.

I was really fascinated by how intricate and yet highly reliable the network protocols are, being built on top such unreliable channels. I am interested to take higher level modules in computer networks, but my friend (who knows better, supposedly) advised me not to. Have not decided whether to heed his advice or not.


CS2107 Introduction to Information Security
Lecturer: Chang Ee Chien

This module is usually taught by Hugh Anderson, but for some reason another lecturer takes over for last semester. He is not very good at teaching, though I can tell that he knows his stuff. The midterm was super easy, as opposed to the finals which require you to understand the things taught in lecture, and think critically what was possibly being compromised, . 

The "difficult" finals was to my relief, because I was so disappointed in the module for the whole semester as it felt so GEM-ish (general knowledge, not so into the CS aspect). To my pleasant surprise, the finals require me to apply what I know and give some creative answers (to some extent, because ultimately there will be a "correct" answer so that he can mark our paper objectively).

There will be an open-ended presentation at the second half of the semester. There will be topics provided, but you are free to propose your own. I took one of the given topic on TOR network. I'm glad I took it because I would not have learned about TOR if I did not. (I am lazy to learn new things if there is no benefit in the short run, unfortunately)


CS3241 Computer Graphics
Leturer: Alan Cheng Ho Lun

This module has been taught by him since forever, apparently. As the lecture notes, tutorials, and lab assignments are the same for the past few semesters. Regardless, this module is really good for various types of people: whether you are really interested into taking Visual Computing or Interactive Media focus area, just want to look around, or want to understand what those graphics settings in your games actually mean. I fall on the second and third category. The module goes for breadth instead of depth, which is why I said it is suitable for a wide range of people.


CS3243 Introduction to Artificial Intelligence
Lecturer: Low Kian Hsiang Bryan

I hoped this module to be more interesting, but as it turned out, it was not really. It is highly algorithmic on the first half and very logic- and statistics-based on the second half. The first half we were taught many graph-search algorithms (which is how most problems are modeled for AIs to solve in the past, like the Enigma machine problem and most turn-based games like chess) eg Minimax, Constraint Satisfaction Problem, and A-Star search. Second half would be about logical agents, and last topic is on supervised learning. Despite the syllabus arranged in that way, the term project was on Machine Learning (creating an AI for tetris), so you need to learn supervised learning in advance (before it is covered proper in lecture) anyway, which I find quite stupid.

The midterms and finals are all about tracing the algorithms instead of solving problems. Although I would not like it on normal circumstances, the fact that I overloaded that semester (I took 25 MCs) means I did not need to study too hard for this module to get a decent grade (I hope, the grade has not been released yet).

LAC3202 Chinese 4
Lecturer: Doris Chen Poju (Chen Boru? I dunno...)

Nothing much to say. If you are going to take this module, most probably you have taken the other lower level Chinese modules. They are basically the same, except you need to write longer essays as compared to Chinese 3.

For the benefit of those who never take Chinese before (perhaps because you took the placement test and got Chinese 4 straight away), you are basically following the textbook (新实用汉语课本2, 第二十到二十六课). Learn vocabs (if you don't know it already), practice the conversations in the textbook, learn sentence patterns (or as they call it, grammar, though I feel that Chinese does not have a grammar the way English does). Exams are similar to workbook questions, except they are a bit harder. There will be 2 口语 at the end of the semester, one is in the form of presentation about Chinese culture, and the other is conversational 口语.


CS3211 Parallel and Concurrent Programming (dropped with W grade)
Lecturer: Hugh Anderson

I took this module with expectation to be taught how to write codes that can run on different threads properly. As it turned out, it was more theoretical than I hoped. Also, the burden of taking 29 MCs has gotten into me so I decided to drop this module in week 6. The lecturer himself is pretty good (I mean, this is Hugh, come on!), but it's just that the course is too theoretical to my liking. But I guess I should have practised myself instead. Considering taking it again next year (only offered in sem 2 =/)

So that's all. Sorry if it got shorter as it progresses as I got exhausted after a while writing it haha. Maybe I will edit it in the future if I have the time and willingness (unlikely, so don't count on it, unless there is a demand for it).

Hopefully the next post will be more useful for my portfolio, or at least for my own knowledge.

Monday, August 18, 2014

Idea 2: (NUS) Lost and Found!

This is an idea that I have just came up with yesterday. I was in the PC commons waiting for my friend to print some stuff, when I helped myself to a vacant PC there and found a(nother) thumb drive being left behind, still stuck into the machine. Any other day, I would have just ignored it as it actually commonly happens, but for some reason, on that day, I thought of an idea for a small Android app for lost and found!

The basic idea is that if we found something, we can take a picture of it and post it into the stream, where people who lost something can try their luck and find their lost stuff there. People can send a request to the founder to claim the stuff, and the founder should ask a question pertaining to the item to verify if the requester is really the owner of the item found.

I know this leaves so many loopholes (people can claim things that are not rightfully theirs) but what I need to do now is not a flawless app; just an idea of an app that I can work out. I do not know if this idea going to remain as what it is; an idea, but I have a plan. Now that I am already back in NUS, I just realized that I actually have the best platform to work on my ideas and getting help at the same time; Friday Hacks of NUS Hackers! We shall see if this project (as well as the previous one) can be done within this semester, with the help of Friday Hacks, or even a Hackathon, if my friends are up for it hahaha.