What always surprises me is that so many don't know or use the directory stack commands, pushd and popd. I'll admit I was also ignorant of them until something like 2005, but once I learned of them I switched and never looked back. Now I can't see someone write or type "cd" without a little bit of a cringe.
When i first found out about pushd and popd, i loved them, and used them all the time. These days, i never use them.
The way i work now is that i have a bunch of terminal tabs open. Each tab has a shell which pretty much just sits in a single directory. If i need to switch to a different directory, i switch tabs. A nice effect of this is that each tab builds up a recent shell history specific to the directory it sits in; the shell in the source directory has a history full of build commands, the shell in the installation directory has a history full of start and stop commands, and so on.
This works because i generally use a fairly small (<10) set of different directories, and i don't move between directories much as part of a single task. Partly, this is because i use qualified paths rather than cd'ing around everywhere. I am happy writing (mostly, tab-completing):
vi lib/awesomeapp/dns/client.rb
Whereas a colleague of mine would always do:
cd lib
cd awesomeapp
cd dns
vi client.rb
He might get a lot of mileage out of pushd/popd. But for me, it just optimises something i don't spend a lot of time doing.
I have the same workflow for switching between tabs, although on Mac the default keyboard shortcut for switching Terminal tabs (Cmd + Shift + '[' or ']') was a little too cumbersome. I swapped it out with (Cmd + '[') which by default will take you to the next Terminal, not tab. I move left to right more, so it made more sense for me.
Easy enough to change in system preferences, though. And with using Vim NERDtree, or some other directory plugin, it makes sitting at the top level directory of your project, with multiple projects in multiple tabs, pretty easy.
Are you on Mac? If so, have you done anything to make tab-switching easier/faster? I'm interested because I only recently set mine up this way, and am always open to more efficient methods.
A related trick is to use parentheses to create a subshell, in the case where you have a fixed command sequence you want to execute in another directory but you don't want to stay there:
Many people love them, but I never got the hang of pushd and popd. These days, I use a CDPATH and z[1]. I also use zsh, which supports handy little things such as cd - (cd to previous directory).
If you haven't tried it, I highly recommend z. It's impossible to Google for, but it's oh-so-convenient.
cd is a shell built-in, not an external command. It has to be, since it changes the directory of the shell process, which can't be done by a child process. So shells do have to implement this specially.
I tend to use "cd -" instead, which goes to the previous directory. Coupled with searching the command line history (C-r in the default emacs-like mode of bash, ESC-/ if you have set vi-like mode with "set -o vi") you can move around quite fast and with little thought.
uhh... I have known pushd and popd for quite a long time, but never realized that pushd can be used in place of cd. So what I have been doing all the time is:
I've always just relied on zsh to deal with my pushd stack automatically. I don't frequently need to pushd (thanks to tmux's vertical splits), but when I do, it's inevitably something I don't think about until after I've swapped directories.