The C++ and Boost Code Shop

Saturday, February 17, 2018

The key is to know which keystrokes to use, and you should use Ctrl-X followed by Ctrl-O in insert mode to bring up completion suggestions in a pop up. If you want automatic pop ups as you type, YouCompleteMe is supposed to work. I couldn't get it to work, and it wouldn't work on some of my setups because it requires a more recent version of vim (7.4.15xx) than I have.

So what was needed? Assuming your GOROOT and GOPATH are correctly set up (if not, see below), the following is all that you need to do:

The above will install additional go command-line tools and you should be all set. Just one more thing. Open you /etc/vim/vimrc file (if you have root privileges) or your ~/.vimrc file (which you could copy from /etc/vim/vimrc) and add or uncomment the following lines:

filetype plugin on
if has("autocmd")
filetype plugin indent on
endif

You can see what it should look like when you edit go code and press Ctrl-X followed by Ctrl-O in insert mode.

The screenshot gif was created on Ubuntu 16.04 using peek, along with gifski.

Setting up your Golang development environment

Installing the latest golang development environment (currently go 1.9) and setting it up involves the following steps:

The key is to have GOPATH set correctly. Also set up glide for better vendoring / package dependencies.

go get github.com/Masterminds/glide

You create / checkout all your projects under $GOPATH/src. If you clone a github project, it should be under $GOPATH/src/github.com/<user>/<repo>. Using go get to get go packages would also clone the repos under these paths.

Wednesday, November 29, 2017

Java alphabet soup

Trying a Java refresher, more specifically a Spring refresher, has so far been a source of mixed emotions. Having written a lot of Core Java in the past and used a smattering of Spring, the utility of either wasn't in question in my head. But then having developed tons of Ruby on Rails apps, and seen both its magic and seamy sides, my perspective perhaps has more dimensions to it today.

I found the Java / Spring way of developing web applications a little too archaic by today's standards. All the annotations have still not exorcised much of the esoteric XML that you still cannot avoid. But Eclipse provides significant relief to the extent that you can get away without writing perhaps a single line of XML, using its Maven and Spring (Spring Tools Suite / Web Tools Platform) plugins instead to add most of the XML content.

You still need to manually configure Tomcat, manually configure data sources and JNDI for accessing your data sources in server specific ways. You still have to manually configure your web.xml. Those are hard, and you have to know at least what to search for in google, and then what to search for in the documentation that google lists. It is frustrating if you don't have a very good, precise tutorial or howto. It all shows the struggles of an old and evolving framework in trying to remain usable even as it remains solidly relevant. I suspect Spring Boot, something I am yet to explore, would bear signs of some true-north evolution. In the meantime, one hopes Java comes up with more modern web frameworks. Spring is mature, stable, mildly usable and very useful. But it feels a decade behind. Spring addressed usability problems of Java EE. But today, something else needs to do that for Spring. Spring Boot may be an evolutionary step in that direction, but more needs to be done.

Saturday, November 11, 2017

Setting
up repos of .deb packages for Ubuntu may not be something people need
to do often on their own laptops. But I was recently doing something
where it made sense. I was setting up a kubernetes cluster using VirtualBox on my Linux laptop and wanted to
automate the whole process using vagrant and ansible. This meant that
each time a VM would be spun up, I would add apt repositories to it and
then install docker.io, kubeadm, kubectl, kubelet, and kubernetes-cni
packages. All of these VMs were to be on my laptop, and each time they'd
reach out to google's or docker's repos to pull these packages in. A
sum total of around 70 MB isn't big but I could be spinning up tens of
VMs over the course of my experiments and a fresh download off the web every time
is a terribly inefficient use of bandwidth (certainly here in India). So
I wanted to setup an apt repository locally on the host laptop which
runs Ubuntu 16.04 (xenial).

The plan

On the host: What we need to do is to run a web
server (Apache2 works fine) that serves a directory with the packages
that I want to host. To make this secure, we need to generate a key pair
using GnuPG, and sign the packages I want to expose. I should also
expose the public key. The packages are .deb files (the analogues of
.rpm on RedHat / Centos, etc.) and in case you've already installed them
on your host laptop, they might be available under the directory /var/cache/apt/archives. If not you can download the packages without installing using a command-line switch for apt install.On the guests: On each guest, we'll need to edit the /etc/apt/sources.list file to include the repository from the host laptop. We'll also need to accept the public key from this repository.

The action

We shall follow the plan outlined above.

Actions on the host

Setting up the webserver and packages

The following will install the Apache 2 webserver and other prerequisites.

$ sudo apt install apache2 dpkg-dev dpkg-sig

The root virtual directory for Apache is by default /var/www/html. You should create the following directory tree under it: /var/www/html/pkgs/dists/$(lsb_release -s -c)/main/binary-amd64. To do that, run the command:

Setting up your key pair and signing packages

If you haven't already, you should generate a key pair using GnuPG.

$ gpg --gen-key

In the prompts that follow, select the key type to be RSA (sign
only), key size to be 4096 bits, key does not expire, and specify a
unique name. Specify a reasonable password. Wait for the keys to be
generated.

Once the key is created, run:

$ gpg --list-keys

Note the line starting with pub like this one:

pub 4096R/B1B197AF 2017-11-11

Note the number appearing after the size specifier (4096R/). Here it
is B1B197AF. This would be your key identifier and would be used in the
next step.

Generate your public key file so that it is accessible through your web server:

Actions on the guest

One point to understand here is that you would want your repository
to be chosen preferentially over others if the packages are present in
your repository. So unless the packages of interest not be present on
other listed repositories, you should put this entry above any other
repositories. The above command appends your repository at the end of
the fail. To move it up in the file, you may need to edit it manually.

C++

Scale / network I/O

Java

Tuesday, September 15, 2015

Moving to git from another version control system like SVN, Perforce or CVS often represents teething pains that don't go away as soon as you'd like them to. But git is a fabulous tool and learning it is worth your while. The following FAQ tries to address frequently encountered scenarios that programmers face when moving to git. It assumes that you understand what a version control system is and have some experience using another system like SVN, Perforce or CVS.

In the Unix tradition, this FAQ is terse rather than elaborate. We don't do visualization of branches and branching models, etc. here. There are better tutorials dedicated to them. The expectation is that in this FAQ you will find answers to the most frequent scenarios that you encounter and know which git command to use. And you should be able to cobble together these commands to solve other scenarios that can be decomposed into these.

Why is Git so complex?Two reasons for it:a. Git is completely distributed - so each developer has a copy of the entire repository and is responsible for keeping this in sync with other repositories.b. As a consequence of #a, operations in Git do not easily map to operations in CVS or Perforce or other popular version control systems.

How do I start on a new project?The most common way is to clone a remote repository. Git supports http, ssh, etc. You need a git URL for a remote git repository and a local directory in which you want to create the cloned workspace. You can then issue the following command:

$ cd local_dir$ git clone git_url

This remote repository can be any repository. Usually there is a designated central repository shared by all members of a development team. But it could as well be another clone of that repository hosted on a different machine.

The remote repository from which the local repository is cloned is conventionally called origin.

How do I checkout a file if I need to change it in my workspace?There is no concept of checking out a file. You cannot lock any files for edit. Just edit it in your workspace.

How do I keep track of which files I've modified?In your workspace, run the following command.

$ git status

It will list files that have been modified, as well as new files that have been created in your workspace.

What is the index and what is meant by staging files?When you add a new file, it is an untracked file. When you modify an existing file, it is a modified file. To indicate your intent of committing them, you need to stage them. You stage a file by running:

$ git add file_or_dir

The index is simply the set of changes you've staged. It is also called the staging area. If you've removed files, to stage the removals too, use the --all switch:

$ git add --all file_or_dir

How can I unstage a staged file?

If you added a new file, you can unstage it thus:

$ git rm --cached file_name

You can unstage all files in the index by running:

$ git reset HEAD

To unset a specific modified file, run:

$ git reset -- file_name

How do I discard my changes to a modified file?

By discarding, you jettison your changes and replace it with the latest committed copy:

$ git checkout -- file_name

However, if the file has already been staged, you will need to unstage it first before being able to discard it (see #6 above).

How do I discard all my local changes?
Run the following:

$ git checkout -- .

If some of your changes are staged, and some unstaged, the above will discard both. If you want to discard only your unstaged changes:

$ git stash save --keep-index
$ git stash drop

How do I check-in a file I have modified?The term check-in is not used in git. Instead you do a two-step synchronization of your local repository with the remote repository.

a. First you make sure that all files you have modified or created in your workspace are committed to your local repository. You do this thus:

You call git add on files that are newly added, as well as those that you've modified. These files are now said to be staged.

b. Next, you commit all these files to your local repository using git commit.

$ git commit -a -m "Commit message"

The -a switch ensures that any modified files are automatically added without the need for calling git add explicitly. You still have to call git add on newly added files.

Each commit is assigned a SHA1 hash (because in a distributed system like git, adding incremental version numbers, which requires global ordering, is very difficult).

The symbolic name HEAD refers to the last commit. HEAD^ refers to the parent of head. HEAD~N refers to Nth commit before HEAD (not including HEAD).

How do I check what files I committed locally?$ git log

This command prints the list of commits in your local repository including their hash values and commit notes. If you want to see the specific files committed and their diffs with the origin, run the following command.

$ git diff origin..HEAD

You can also check what changed between two commits:

$ git diff commit1-sha1 commit2-sha1

How do I keep my repository in sync with the remote repository?$ git pull remote-branch local-branch

This would often (but not always) take the form of:

$ git pull origin master

Read on for more details.

How do I check the diff for staged files? What about files from a specific commit?To check the diff for your staged changes, use:

$ git diff --cached

To check the diff for a specific commit, use:

$ git show commit-sha1

To check the changes in a particular file between two commits:

$ git show commit1-sha1 commit2-sha2 -- path_to_file

I realized that my commit went wrong. How do I fix it?Maybe you left something out that should have made it to your commit. Or you had to make a change to a file that was already in the commit and you want to include that change. Or perhaps it is just the message you wanted to change. Or all of these? Use "git commit --amend".

Amending a commit replaces it with a new commit with a new SHA1 id. Thus amending should be reserved for private branches, or else any branches based off a commit that is replaced by an amend operation would be difficult to manage.

Now that I have committed my changes to my local repository, how do I check them into the remote repository?You don't check-in. You sync with the remote repository using git push. The general command is:$ git push remote-repo local-branch

You keep mentioning "branch", but I don't know what a branch is.A branch is a fork of a source tree. When you clone a repository, your local repository has a single branch called master. You can then create more branches from it as follows:

$ git branch new-branch-name

This one creates a branch from the HEAD of your current, but you can also create branches from other branches, or from specific commits.

$ git branch new-branch-name commit-ref

The commit ref here can be the name of another branch (referring to the HEAD of that branch) or to the SHA1 of a specific branch.

Why do I need branches?Short answer: if you have used Perforce: think of them as Perforce changelists with history.

You need branches to isolate and streamline your feature development, as well as handle releases. You should develop features and commit them to branches.

You can switch between multiple branches in your workspace. If you want to switch to branch mybranch, use git checkout.

$ git checkout mybranch

This will swap the current contents of your workspace with that of the mybranch branch.

* If there are uncommitted changes in your workspace and you switch to a different branch using checkout, the switch will fail if it required clobbering your uncommitted changes.

You can also check all the branches by simply using:

$ git branch

Your current branch will be marked with an asterisk.

I have some uncommitted changes in my master branch workspace but I now want to put them in a different branch. How do I do it?Just create a branch and switch to it. You can do both in a single command:

$ git checkout -b new-feature-branch

How do I make sure that my branch is updated with changes from another branch?Let us suppose you're working on branch my-branch. You can sync your master with the origin:

$ git mergetool runs the configured mergetool on every file with merge conflicts in the current workspace.

I committed something to my master branch but now want those changes in a different branch but not in master. How do I do it?

If those changes were not followed by other changes that you would like to retain in the master, then you can do this.

a. Create branch from master.

$ git checkout -b new-feature-branch

b. Reset master to the last commit before your changes.

$ git checkout master$ git reset --hard last-retained-commit-sha1

Never run reset on a branch you share with other developers. Just like git commit --amend, git reset removes some commits and if such a removed commit is the baseline for some other branch, then that presents a difficult scenario to recover from.

Can I push a branch to the remote repository?Yes. Use git push as show below:

$ git push origin my-local-branch

How can I delete the remote branch I pushed, but retain the local branch?Use the colon-prefixed branch name with git push.

$ git push origin :my-local-branch

How can I delete a local branch?$ git branch -d my-local-branch

The above will delete the local branch only if all commits in the branch are also part of at least another branch locally known. Sometimes, this would require you to pull other remote branches which were not locally updated to ensure that those commits are visible in other branches locally, and then retry the command. If you don't care and just want to delete the branch anyhow, then use:

$ git branch -D my-local-branch

How do I modify older commits?If you can, don't. Work on a single commit per branch, keep amending as needed. Push upstream when you're done. If you still have to tinker with older commits as you sometimes need to do, read the answer to the question "What is the use of rebasing?" below.

How do I trace which commit by which user changed a particular line in a file?$ git blame file_name

How can I undo a commit?You can always undo manually and check-in. When it is the last commit, or you can tell that undoing an older commit will not cause conflicts with later commits, then you can use git revert.

$ git revert HEAD$ git revert commit-sha1

This creates a new commit (you don't need to separately call git commit after this), that undoes the previous commit.

What is the use of rebasing?Rebasing changes the baseline commit of a branch. It is a cool way to merge branches which cleans up commit history nicely. Features are usually developed on separate branches. It is possible that one branch gets merged into the master while development on the other branch is still in progress. When you are done on the other branch and want to merge it back to the master too, you realize that its baseline commit is quite old. At this point you either merge the master into the branch (as suggested but discouraged in #19) and then merge it back to the master, or you rebase the branch. The former approach results in extraneous commits on account of the merge and could bury your own commits in a barrage of other commits that came in the merge. This is what rebase aims to avoid. To rebase a branch, you run the following command:

$ git checkout branch-to-rebase$ git rebase commit-ref

The commit-ref identifies the baseline commit you want to rebase your branch to. It could be a commit SHA1, or a branch name, etc. Frequently, you would want to rebase your branch to the head of a parent branch, so you would simply use the name of the parent branch for commit-ref. This effectively moves the baseline of your branch to the head of its parent branch (or to whatever commit you specified). A merge into the parent following this would be a fast-forward merge and produce a clean history.

Rebase removes some commits and creates new ones in their lieu at different points in the branch. If there are sub-branches based on any of those commits that are removed in a rebase operation, then recovering those branches could be complex.

I hurriedly reset my branch back by a couple of commits and now I realize I lost some important changes? Is there a way to retrieve the lost information?There actually is. We can find the SHA1 hash of any deleted commits only if it is from the last 30 days, by using:

git reflog

From its output, we can identify the SHA1 of a commit that has since been lost due to the reset. For a slightly more detailed output that helps you identify the context of each commit, you can run $ git log -g branch_name. We can then run git reset with that SHA1 as shown:

$ git reset --hard lost-SHA1In case reflog didn't show you what you were looking for (an unlikely event), try your luck by running:

$ git fsck --full

Then go through the listed dangling commits, and blobs (for stashes), and use git show commit-sha1 to list contents.

Could I encounter merge conflicts during rebasing and what do I do then?Yes you could and you have the option of either resolving the conflicts (see #20) and completing the rebase, or discarding the attempt to rebase. Once you have resolved the conflicts, you use the following command to continue the rebase:

$ git rebase --continue

Sometimes the conflict could be bad enough that you have to ditch the attempt to rebase. You could do that with:

$ git rebase --abort

Is there a way to save my uncommitted changes and work on another feature? OR What is git stash?Of course there is. $ git stash provides the easiest way of doing that. When you run git stash, it saves your uncommitted changes and lets you start on clean workspace that is in sync with your HEAD. Once you're done with these changes and have committed them, you could continue on your old changes with $ git stash pop. You can also use it as a "rebase" for your uncommitted changes, if there are new changes upstream that need to be pulled into your working branch:

In case git stash apply encounters a conflict, you need to manually merge and then call git stash drop. Likewise, if you have to rebase your branch and have some unfinished work that you'd like to continue on after rebasing, use the following commands:

Why would you need to apply specific stashes? Stashes are added to a global list. Say you alternate between two branches A and B, and you stash your work on each branch into stashes s_A and s_B. If you now run:

$ git stash pop

it will always apply the last stash on whatever branch you're in. If the last stash you took was s_B on branch B, but you then call

git stash pop

on branch A, then it will apply s_B on branch A. This is not what you usually want. Instead, you should take care to list the stashes out, and apply the correct stash explicitly to the correct branch.

I have some staged files that I'm yet to commit. At this stage I need to pull / merge / rebase on my branch, but it fails because of the staged changes what to do?
Unstage your changes.

$ git reset HEAD

Then follow the above #32.

I committed some files on my local branch but now I want to change them further and not push these commits upstream. Plus I may need to pull / merge / rebase. What do I do?
Identify the last commit you want to retain - say last-good-commit-sha1. Run the following:

$ git reset last-good-commit-sha1

Your changes are now unstaged. In order to now do any merges on your branch, follow #31. If no merges are needed, just make the necessary changes and create a fresh commit.
Also see, git commit --amend, git rebase and git rebase -i. Any command that changes commit history - whether git reset, git rebase or git commit --amend, should be issued only on local branches to edit commits that have not be pushed upstream.

To push such commit history changes upstream, you have to use:

$ git push -f ...

In many repositories, git push -f ... is disabled and for good reason.

I have some changes committed to one branch which I want to pull into another branch without pulling the whole branch?
Identify the individual commits that you need to pull. Note their sha1 ids. Switch to the target branch and then use the

How do I find out how many commits have gone into my current dev branch?

$ git rev-list master.. --count

That's assuming your parent branch is called master.

How do I find out whether a branch contains a particular commit?

You have to do it the other way round. You figure out the branches that contain a particular commit and check whether the specific branch you're interested in is one of them. Use the following command:

$ git branch --contains <commit-id>

I want to move a file from one repository to another (say proj1 to proj2). Is there a way to do it that preserves history?

Yes there is a way, but it won't happen with a single command and will require some manual intervention. So let us suppose you want to move file Foo.java from path src/bar under repository proj1 to path src/baz under repository proj2. Here are the commands you need to run in sequence:

The last command recreates the entire commit history in the target repository (proj2).

Something seems wrong with my working tree / local repository. Pulls / merges don't seem to be working and it is showing unstaged files I haven't even changed. What do I do?
To start with, run:

$ git gc

Make sure no other programs are running git commands on the same repository in the background. This means closing Eclipse, SourceTree, any program that might be running some git commands in the background, etc. You should also periodically clean up your repository of dangling commits, etc. Run the following commands:

$ git fsck
$ git prune

My remote url has changed (i.e. my origin has changed), do I have to clone the whole repository again from the new URL ?
No. You can easily change the origin's URL or the remote URL of your local repository. You can do using git remote command.

$ git remote set-url origin

How do I find out who committed how many files?
You can run the following command:

$ git shortlog -s -n

But do note that the same author could show up with multiple names depending on whether their user name changed or not.

$ git log -n 10 --author=amukher1

How do I create a local branch and push from there into a remote branch?
Do the following:

How do I clone a single remote branch of a repository?
Do the following:

$ git clone <url> --branch <branch-name>

The last step creates a tracking branch.

How do I update a local branch from its tracking branch?
Simply type:

$ git pull

How can I add an existing repository to github?
Create a new repository on github using the web interface. Let's say its call newrepo. Now go to your local repository root dir and run the following commands.

Thursday, February 05, 2015

Today I learned two beautiful words. Vignette is a word I had a passing familiarity with but one I would never have managed to use in a sentence until today. A vignette is really snapshot or a short passage from a play or movie, or perhaps even from the events of our lives and times. I think it is most used for a snapshot or a passage that is unique or iconic in some way - perhaps a distillate of the wider work itself. I can instantly think of vignettes from my life, the ones since my daughter's birth till this time being the most meaningful for me.

The other word is solipsism. At one level, it describes as state of extreme egocentricity. In a more general, non-individualistic context though, I think it represents one of the most predominant positions of our times - the feeling that there cannot be another perspective or point of view, different from our own.

Thursday, January 08, 2015

Tired of going to the same places over and over again, and wondering where to head to for some lip-smacking good food in Pune? Here is a short reckoner.

[Photos coming soon.]
[Disclaimer: Highly subjective and skewed towards west Pune, Continental cuisine. The emphasis is on taste and value-for-money, casual dining than on fine dining.]

In no particular order, here is my list of 20.

1. Le Plaisir – A tiny bistro with a big heart on Bhandarkar Road. Must try Croque Madame sandwich, sachertorte and red velvet cake. Their macarons are among the best in town. They are open only till 9.30 pm.

2. Tien – A pretty unique bistro in Model Colony that serves Japanese, Mexican and Continental. Top stuff here including salmon and prawn sushi and nice Thai curries. But I especially like their Hot Chocolate. They close at 10 pm.

3. Wholly Crepes – Right next to Tien and the crepes here – sweet and savory – are yummy.

4. I M Lion – Maharashtrian coastal and Goan meat and fish delicacies cooked with home-made recipes and masalas, at very good prices. I haven’t had better kombadi vade. Their fish preparations are absolutely top-notch. Location: Bavdhan, near Aditya Shagun Mall, next door to Axis Bank.

9. Rajmandir Ice Creams – They are a branch / clone of the original Kolhapuri Rajmandir ice creams. If you haven’t tried their peru (guava) ice creams sprinkled with red chilli (yes that’s right) you haven’t let your tongue explored a new dimension of taste yet. Have it to believe it. And it’s cheap. Location: Karve Road.

10. Café Mezzuna – Run by Speciality Group and right next door to Mainland China on Boat Club Road, this place serves some fine European cuisine. Try their lamb chops, pork ribs and all the fish / sea-food. And yes, the crème brulee and panacotta.

11. German Bakery - Loved their beef stroganoff, fish n chips, bun masca (garlic bread rolls infused with butter) and the variety of teas. Haven't been to the newly opened one on Law College Road (in place of the old Mocha Cafe).

12. Pink Butter Cafe - Located in 1 Modibaug near the FC Road crossing flyover, being here is an experience in itself. Done up like a doll house with baby pink walls, comfy seats, and with beautiful French music playing (Charles Aznavour, Alain Barriere, France Gall and a certain Edith Piaf), this place alongside its twin boutique Mairah is a unique bistro that serves some lovely teas, scones and crepes, not to mention the super awesome pastries. Must try: Hazelnut Belgian Chocolate crepes, Hazelnet Mousse cake, Cointreu orange zest crepes, etc.

13. Curry Leaves - On Baner Pashan Link Road, Curry Leaves is the best non-veg Keralite food place this end of the town. It is quite cheap, and pretty decent on space and cleanliness. What to try? Definitely their egg appams with any of their spicy curries, roasts or fries. But if you like beef, ask for Potu Fry (not on the menu).

14. Papajee’s – Spine Road in the back of beyond industrial belt somewhere between Pimpri, Bhosari and Akurdi, you don’t go there without a GPS on phone and plenty of energy to drive. But once there, you can expect some authentic dhaba style non-veg and veg-food and excellent naans unlike anything you get in Pune. A pretty good Punjabi meal!

15. Stew Art – Tucked away in a lane near MIT College (Rambaug Colony), this small eatery claims to be India’s only Stew Restaurant. Reasonably priced full meals of stew served with rice and some fab brown bread, it’s worth a few visits. Try their Hungarian goulash and Stroganoff stews. The food is more fresh and guilt-free than rich and lip-smacking but a very good option to eat out if you want something light on the pocket and the tummy.

16. Smiley House – Authentic Vietnamese cuisine in a small eatery run by mom and daughter. If you like light flavourful meals, you’d love most of their stuff. Not many options for vegetarians and service is quite slow. Their Vietnamese Cold Coffee is quite a treat but the trick is to let the ice melt. Location: Behind Medipoint Hospital Aundh, near Smokin' Joes Pizzas. Open only till 9.30 pm.

17. Akhtar’s Samosa’s and Kebab Pav next-door – Standing at the head of Saifee Lane (parallel lane between East Street and MG Road not too far from Baghban), Akhtar’s Samosa cart sells meat-filled patti samosas that are cheap and tasty. Next to him stands another guy who sells chicken and beef kebab pavs at 15 rupees a piece.

18. Café 1730 Beans and Booze – Lane 8 Koregaon Park near Sanskriti Lifestyle – great place to hang out and have finger food, including some reinvented Goan classics.

The best:
19. Le Boucheé d’Or – A small piece of heaven on Puneri earth, it means mouthful of gold and it’s worth the name. It’s a French patisserie/boulangerie run by expat chef Brice Poisson. They are expensive but let that not be a deterrent. What to try: especially the Almond Chocolate / Pistachio Chocolate / Almond / Pistachio croissants, the raspberry cheese cake, apple pie something. And yes, the best macarons in town. They are on Boat Club Road near Mainland China, and also in Aundh next to DAV School on DP Road. They are open only till 7.30 pm, true French defiance.

20. Stone Water Grill – Yes SWG has been reinvented and their emphasis on gourmet fine dining has only got bigger. The food is fantastic, the prices equally so. Put on a swanky look, go there and splurge, but enjoy the great continental food. Location: Koregaon Park Annexe, near Hard Rock Cafe.