Using Multiple Working Directories in both Mercurial and Git

I’ve been told that utilizing this functionality is terrible, bad practice, a mistake, contributes to climate change, etc. However, it fits into my workflow pretty well, and it might fit into yours as well. After all, it is implemented in at least two version control systems…so some people must find it useful, right?

I use both Mercurial and Git depending on the project, so I’ll briefly describe the usage for both, with references to more complete documentation at the end. While the implementation is different, in both cases there are essentially multiple working directories for a single repository.

Use Cases

I only use this feature as the sole committer to a local repository; any interaction with other developers is done via a normal DVCS push/pull workflow. This feature allows for working on multiple branches (or any commit/checkout) from the same repository using different working directories. There are a few situations I’ve run into where this is helpful:

  • The build process is time consuming and generates a lot of artifacts – This streamlines working on multiple branches simultaneously.
  • Items outside of the repository are referenced – Having to switch out the references between branches can be a pain, but with multiple directories it’s not necessary.
  • Comparisons between different versions of a project – This especially streamlines situations where you need to compare several files at once, or make modifications as you go.
  • Flexibility – While light branching is great, sometimes it’s nice to be able to experiment in separate directories without needing to shelve/stash those changes every time work is needed on a different branch.

There are other workarounds for these types of problems, but this method is straightforward and simple (assuming that you’re aware of the pitfalls).

The obvious question is why not just clone the repository? With multiple repositories, you need to make sure to keep them synchronized, which can be easy to overlook sometimes (e.g. a branch you only work on every once in a while).

This becomes a bigger issue when you often have to pull in upstream changes from one or more sources. With repository clones you need to make sure that all of them get the latest updates every time. On the enterprise or team level this can be easily automated, but at least in my experience, for a single user simply having multiple working directories is easier to manage.

Another workflow that I haven’t used myself but may be interesting is to have your “real” repository be “bare”, or not have a checkout. Then individual branches can be checked out in separate working directories, all referencing the real repository. This is similar to the primary model supported by the Bazaar VCS.

Mercurial (hg share)

Of the two, Mercurial’s approach is more simplistic. It utilizes the “share” extension, which is bundled with Mercurial but needs to be activated in your configuration:

[extensions]
share =

You can then create a share.

hg share <source> <destination>

When creating a share, you have the option whether or not to create an empty working directory, and whether or not to share bookmarks.

In Mercurial this functionality doesn’t provide much in the way of safety nets. It’s best to avoid any destructive operations (e.g. rollback, Mercurial Queues usage, HistEdit, etc.) as the state of the other working directories could easily become invalid. Verifying that you’re working on separate heads isn’t a bad idea either, be it just via the directories, or more explicitly via bookmarks or branches.

Git (git worktree)

In Git, this functionality offers some additional features and safeguards. It works out of the box.

From an existing Git repository you can run the following command to create a separate “work tree”:

git worktree add <directory>

You have the option to specify the branch, create a detached HEAD, and whether or not to lock the work tree. Among other things, locking a work tree prevents it from being moved/deleted. Git also provides the ability to list the current set of working directories for a repository via the git worktree list command.

By default Git will prevent you from checking out a branch that is already checked out in another directory, but that can be forced. As with Mercurial, be careful to avoid any destructive history rewriting. According to the documentation this functionality should also not be used with submodules.

References

Hg Share Extension: https://www.mercurial-scm.org/wiki/ShareExtension
Git worktree: https://git-scm.com/docs/git-worktree

Blender Tip – Manage Hotkey Configuration Entries (and Remove Duplicates!)

There are several ways to assign a hotkey to a particular piece of functionality in Blender. The most well-known is probably right-clicking on a menu item and selecting Add Shortcut, which works great most of the time. Once applied, shortcuts can be changed or removed in a similar manner via Change Shortcut and Remove Shortcut. However, it is possible to get into a situation where a key combination is applied that cannot be removed in this manner, and cannot be re-applied to another piece of functionality. The method below can be used to remove these duplicate assignments.

Hotkeys can also be managed via the Input section of the User Preferences window. Among other things, the screen allows you to search for a hotkey combination either by functionality name or by the actual hotkey combination.

Hotkey Search Screen

Once you have located the functionality and/or hotkey combination you were looking for, you can edit or remove a particular binding to resolve any issues. Be sure to click Save User Settings at the bottom of the screen once you are done in order to make the changes persist to your next Blender session.

Hotkey Search Results

This is particularly handy when you have multiple add-ons and end up trying to use the same hotkeys for different functions (pro-tip: don’t do that).

If you want to save a configuration (or multiple configurations) so that you can recall it later, you can do so via the dropdown menu to the left of the search. There are a few built-in presets (Blender, 3DSmax, Maya). Similar to other areas of Blender (e.g. themes), you can add a new preset with the + button.

Hotkey Preset List

Making PulseAudio 10 work with X Windows and Firejail

I was unable to find much information about this issue so it’s either somewhat obscure or I’m terrible at searching for things. Probably both.

Background

I originally ran into this problem when trying to run Firefox in Firejail using the standard Firejail profile for Firefox. Firefox ran fine, except there was no audio. I found that this was a known issue documented here, but unfortunately none of the suggested fixes had any effect. The page states that newer versions of PulseAudio do not exhibit that issue, so that is not really surprising.

I did some searching and found others with related issues (see the related links at the end of this post), but no solutions matched my problem. Based on some of those discussions I tried to run speaker-test with Firejail (both with and without --noprofile), but I received a “connection refused” message in both cases. After some experimentation I found that if I ran speaker-test in Firejail after booting up, but before starting X Windows, it worked. This was the case even if I first used an audio program in the terminal (e.g. a music player) before attempting to run a program with Firejail.

Extra background – The system in question runs Slackware Linux (-current) with PulseAudio 10, starts up into runlevel 3 and uses startx to load X Windows.

Solution

I was able to resolve the issue by adding the following to my .xinitrc before starting the window manager. It starts PulseAudio via the start-pulseaudio-x11 program, which (according to the man page) adds access credentials to the PulseAudio server to the X11 root window and registers it in the X11 session manager.

pulseaudio --kill
start-pulseaudio-x11

I doubt this is an issue for those that start their system using a graphic display manager, although I have not tested that.

Possibly Useful PulseAudio Links

Accessing GUI Applications with “su” in X Windows

There are many solutions for accessing GUI applications (in X Windows). Several are described in this excellent post on the Arch Linux Wiki.

However, I needed a different solution as I frequently “su” to different accounts in the terminal to perform different tasks – I normally don’t just start one application and then exit back to the original user.

I ended up finding an answer in the xhost man pages (go figure). The command below should be run as the user who started the X Windows session. Substitute the actual username of the account for the “su” in place of “USERNAME”.

xhost +"si:localuser:USERNAME"

The si prefix stands for “server interpreted”. This syntax allows us to grant access to a single local user. For more information check out the man pages for xhost and Xsecurity.

Managing the “internalBorder” background color in rxvt-unicode

Setting the Internal Border Size

While by no means an “essential” setting for many users, the internalBorder setting in rxvt-unicode can go a long way towards making the terminal more readable or simply looking more the way you want. It adds some padding between the edge of the terminal window and the start of the text, both at the top/bottom and the left/right of the window. This is especially useful if you use a tiling window manager and do not otherwise have spacing between windows.

To set the internal border, simply add the setting below to your Xresources file. In this case it sets the border to five pixels.

URxvt.interalBorder: 5

You should be able to use xrdb -load filename (replace existing properties) or xrdb -merge filename (merge with existing properties) to load the settings without restarting X Windows. You will need to open a new terminal window to see the effects.

Changing the Background Color

If you set the background color of your terminal dynamically with a script such as base16-shell, you may notice that the background color of the internal border of the rxvt-unicode window is not set.

The internal border looks for the number 708 in the escape sequence used for setting colors, whereas the sequence for setting the normal background color uses 11. For example, to set the background color to a nice grey color (#c3c3c3), you can run the command:

printf '\033]11;rgb:c3/c3/c3\007'

The internal border background color can be set to the same value using:

printf '\033]708;rgb:c3/c3/c3\007'

In terms of the base16-shell scripts, one option is to modify the template, copying the line that sets the background to also set the internal border background color (the default.moustache file here). In that case you’ll need to rebuild the scripts using one of the builders as shown here.

You can also use a shell command utilizing sed like the one below to copy the line that sets the background color in the scripts and create a new line to set the internal border color.

Example Shell Command:

BASE16_SCRIPTS_DIRECTORY=/your/script/directory
for script in ${BASE16_SCRIPTS_DIRECTORY}/*.sh; do
    sed -i 's/printf \$printf_template_var 11 \$color_background/&\
    \printf $printf_template_var 708 \$color_background/' ${script}
done

Modification Result:

printf $printf_template_var 10 $color_foreground
printf $printf_template_var 11 $color_background
printf $printf_template_var 708 $color_background

Note that the base16-shell scripts have special handling for iTerm2 and tmux, so if you use either of those tools, you should also update those sections accordingly.

References

http://unix.stackexchange.com/a/169474 (rxvt-unicode internalBorder)
http://unix.stackexchange.com/a/295520 (changing terminal colors)
https://github.com/chriskempson/base16 (base16-colors)