How to create and use multiple P4 workspaces

It is sometimes useful to have more than one workspace in Perforce. I have found that this gives me more freedom to work on multiple bugs or features at the same time for the same branch.

  • To create a new workspace, we create a new P4 client. To do this, you need to provide a new client name:
$ p4 client my_client_2

This opens the configuration of a new client named my_client_2 in your favorite editor. Here you can provide the root directory for this client and mappings as your normally would. Save and exit the editor.

  • Create the root directory path you specified in the new client config:
$ mkdir -p /home/joe/p4_workspaces/my_workspace_2
  • You need to set this client name as the current client to inform P4 that its commands apply to this client. You do this by setting the P4CLIENT environment variable:
$ export P4CLIENT=my_client_2

Now you can run commands such as sync and they should work in this new workspace.

  • Switching between two or more P4 workspaces gets onerous if you need to set the above environment variable every time. One solution to overcome this is to create a P4 config file in the root directory of every workspace with the environment variables you want applied for that workspace.

Create a file named .p4config in the root directory of the new workspace, /home/joe/p4_workspaces/my_workspace_2 in this example, with the environment variables and their values you want to set:


Now when you are at any child directory of the new workspace, P4 will know that it has to use the above client config for its commands. You need to place such config files at the roots of all your workspaces to have a pleasant working experience when moving between workspaces.


Okular does not allow review on PDF


I sometimes use Okular to annotate a PDF using highlighting, drawing boxes, underlining or writing notes. This feature is called review in Okular. However, I noticed that this review feature is disabled on certain PDF files. I did check the filesystem and the file was not readonly.


Turns out that when a PDF has DRM options set in it, Okular obeys those limitations by default. Thankfully, this can be turned off easily. Go to Settings → Configure Okular → General and uncheck the Obey DRM limitations option. You will need to restart Okular after you apply this. You will now be able to review the PDF.

Tried with: Okular 0.24.2 and Ubuntu 16.04

JIRA 7 Essentials

JIRA seems like a great issue management system. However, I found myself terribly inept when it came to using its features, especially because I was not familiar with agile software development practices. Wanting to get a quick introduction to JIRA I read JIRA 7 Essentials by Patrick Li. This short read is in its 4th edition and this latest edition covers the latest JIRA 7.x, which is also what I wanted to learn about.

The book is written for JIRA administrators, project managers and normal users. Administrators are the folks who install JIRA and configure it. Managers create projects and control the permissions for normal users. About half the chapters in the book covers topics for these two categories of users and I could conveniently skip those cause I am neither. The chapters for normal users covered everything I was hoping it would.

Chapter 2 covered the main project interface and it features. I found Chapter 3 on Agile Projects very useful since it showed how to use JIRA for both SCRUM and Kanban style of working. Chapter 4 was the most important one for me because it covered issues which are what you primarily work with in JIRA. Finally, Chapter 10 explained how to use both the simple and advanced JQL methods to search for issues and save and use them across JIRA.

I learnt a lot of useful things from this book that I would not have in daily usage of JIRA. For example, JIRA has keyboard shortcuts in the issue UI for the most common actions. I was also not aware of the share, export, vote and time log features in issues. I also learnt how to create SCRUM and Kanban boards for my epics and sprints. Also useful was the addition of gadgets to my dashboard. I found myself comfortable creating boards, saved search filters and with JIRA jargon in general. All in all, I got a satisfying bang-for-buck for the half day I spent leisurely reading through this book. If you are new to JIRA, I highly recommend getting a book like this one to learn how to use it effectively. In case you have access to O’Reilly Safari, this book can be accessed there.

p4 changelist cheatsheet

A changelist in Perforce is identified by an unique number and contains a list of modified files and a description (among other things). When you inform Perforce that you have created a file, deleted a file or modified a file, such changed files are by default added to a default changelist that has no changelist number.

  • To create a changelist by grabbing the files in the current default changelist:
$ p4 change

This opens your default editor to a temporary text file showing an empty description and the list of files from the default changelist. You have to use the editor and provide a description. If you do not want some of the files to be in the changelist you are creating, you can delete those lines in the editor. Once you save the file, the changelist is created with a unique number identifying it. After this command ends, p4 prints out its changelist number, say 123456.

Note that this command moves all the files in the default changelist to the new changelist you created. That is, unless you removed a few of them while creating the changelist.

  • To view all the details of an existing changelist 123456:
$ p4 change -o 123456
  • To add a new file to an existing changelist 123456:
$ p4 reopen -c 123456 joe/foobar.cpp


  • To view the description of a changelist:
$ p4 describe 123456
  • To edit the description of an existing changelist 123456:
$ p4 change -u 123456


  • To shelve the files from a changelist 123456:
$ p4 shelve -c 123456
  • To list the files in a shelved changelist 123456:
$ p4 describe -s -S 123456
  • To update a shelved changelist 123456 with newly updated files from disk:
$ p4 shelve -f -c 123456
  • To update a shelved file with a particular changed file from disk:
$ p4 shelve -f -c 123456 foobar.cpp
  • To delete the shelved files of a changelist:
$ p4 shelve -d -c 123456
  • To delete a few files from a shelved changelist 123456:
$ p4 shelve -d -c 123456 joe/foo.cpp joe/foo.h


  • To unshelve the files that were shelved from a changelist 123456 back to the same changelist:
$ p4 unshelve -s 123456 -c 123456
  • To unshelve the files that were shelved from a changelist 123456 back to a different changelist 789012:
$ p4 unshelve -s 123456 -c 789012
  • To unshelve the files that were shelved from a changelist 123456 back to the default changelist:
$ p4 unshelve -s 123456


  • To create a changelist from the default changelist and submit it to your branch in the depot:
$ p4 submit
  • To submit a changelist 123456 to your branch in the depot:
$ p4 submit -c 123456

Scanner in use error


I connected a HP DeskJet 2130 printer-scanner to my Windows 10 computer and installed its driver. I opened the HP Printer Assistant application and tried to scan a page and got this error:

The scanner is currently in use. Please wait until your previous task is complete and then try scanning again.

The error would not go away even if I restarted Windows or restarted the printer-scanner.


This error is extremely misleading because the scanner was not in use. After some trial and error I figured out the real cause of the error: the door to load the printer cartridge was open. I closed that, restarted Windows and restarted the device. I was able to scan without a problem after that.

How to mount remote directory on Windows using SSHFS-Win

sshfs makes it convenient to mount a directory from a remote Linux computer on a local Linux computer. SSHFS-Win makes it easy to mount a directory from a remote Linux computer on your local Windows computer.

  • Install the latest stable installer of WinFSP from here.

  • Install the latest stable installer of SSHFS-Win from here.

  • Open File Explorer, right-click on This PC and choose Map network drive. Choose a drive to mount at and in the Folder field enter:


By default, Windows will use your Windows password or credentials for the remote computer. If the password or credentials are different on the remote computer then choose the Connect using different credentials option.

Windows will ask for your password at the remote computer. After that the home directory from your remote computer will be mounted at the Windows drive you chose. I found that I had full read-write access to the files mounted from remote.

Tried with: SSHFS-Win 2.7.17334 and WinFSP 1.2.17346

How to edit remote files using Remote VSCode

Visual Studio Code is a great editor for local files. Remote VSCode is an extension that enables editing files on remote systems in your local VSCode. Note that you will need to specify individual files on the remote computer and they will appear in your local VSCode. You cannot open a remote folder and expect all of the code there to be indexed for code browsing with this method.

  • Install rmate on the remote computer. rmate has been ported from its original Ruby implementation to Python, Bash and other languages. I like to use rmate-python. Installing it is easy:
$ sudo pip3 install rmate
  • On your local VSCode, install the Remote VSCode extension from here.

  • Open Preferences → Settings and in the User Settings window, add the following settings:

//-------- Remote VSCode configuration --------

// Port number to use for connection.
"remote.port": 52698,

// Launch the server on start up.
"remote.onstartup": true

// Address to listen on.
"": ""

// If set to true, error for remote.port already in use won't be shown anymore.
"remote.dontShowPortAlreadyInUseError": false
  • Restart VSCode and run the command Remote: Start server by pressing F1.

  • SSH to your remote machine with port tunneling:

$ ssh -R 52698: yourlogin@remotecomputer
  • Once you are SSHed into the remote computer, run this command there:
$ rmate -p 52698 file/you/want/to/edit

The file will appear in your local VSCode for editing. The remote file will be updated with any changes you make locally after you save the file.

Tried with: Visual Studio Code 1.22.2 and Remote VSCode 1.1.0

How to convert Unix and Windows paths in Cygwin

Cygwin uses Unix paths. It can be sometimes confusing to figure out where in the Windows filesystem a Cygwin path is actually referring to. This is precisely why Cygwin ships with the cygpath tool.

  • To print the Windows path of a Cygwin Unix path:
$ cygwin -w /some/unix/path
  • To print the Windows path of a Cygwin Unix path in a DOS-compatible path format:
$ cygwin -d /some/unix/path
  • To find out how a Windows path can be accessed inside Cygwin as an Unix path:
$ cygwin -u "C:\Windows"

How to specify number of bits in a byte

In C and C++ code, I sometimes need to specify the number of bits in a byte. For example, when creating a bitset object. In old architectures, the number of bits that make a byte has varied, from 1 to 48 bits. But for all practical purposes today, 8 bits make a byte. However, I am not comfortable using the magic number 8 in my code or creating a new constant variable with that value whenever I need it.

Thankfully, the C and C++ standards have a constant for that: CHAR_BIT. It is defined in limits.h and climits. It is guaranteed to be set to the number of bits in a byte on the architecture you are running on.

How to use clipboard for Vim in VSCode

Visual Studio Code has a decent Vim extension. I use it by default and sometimes wish I could yank to and paste from the system clipboard. Thankfully, this feature is available in the Vim extension, but turned off by default.

To turn on this feature, set the vim.useSytemClipboard setting to true. You may need to restart VSCode for it to take effect.

Note that you can yank text to the clipboard of your OS and also paste from it into VSCode using Vim.

Tried with: Vim extension for Visual Studio Code 0.11.5 and Visual Studio Code 1.22.2