Monday, December 28, 2015

Demo to show fail-safe branching & merging in git


The motivation for this post was to demonstrate that git "does the right thing" when merging branches, allowing you to get work done quickly & easily.

Using older tools like CVS and Subverion (SVN), creating and merging branches frequently was difficult and error-prone.  Git makes things much easier.

The first thing to keep in mind is that a "branch" in git is really a misnomer, as a git branch is fundamentally different from a branch in SVN or CVS. Suppose we have the following commit history:

  A--B--C--D
   \
    E--F--G

where the ID numbers are arbitrary "placeholders" for the actual source code.  In CVS or SVN, a branch would refer to an entire linear structure, either A-B-C-D or A-E-F-G.  However, in git, a "branch" is really just a pointer to one of these code blobs:

           aa
           |
  A--B--C--D
   \
    E--F--G
    |     |
    cc    bb

Here, we see 2 "branches" aa and bb (aka "blob pointers"), each of which points to one of the two newest code blobs. Note that we also have another branch cc pointing at blob E, even though it is not one of the newest blobs. As we modify the source code & commit changes, git will add new code blobs to the history graph and will automatically update our blob pointers (aka branches) to point to the newest blob (most of the time).

Onward to the guts of the post!

For the purposes of this post, we will use a few convenient aliases (bash/zsh syntax):

  alias d="ls -ldF --color"
  alias gits="git status --short"
  alias gitb="git branch"
  alias gitcam="git commit --all -m'misc' "
  alias gitdw="git diff --ignore-all-space --ignore-blank-lines"
  alias gitco="git checkout"
  alias gitlg='git log -22 --oneline --graph --decorate' 

Create an empty directory containing a file and number 5 lines like so:

  ~/tst > d *
  -rw-rw-r-- 1 alan alan 11 Dec 28 15:27 ff.txt
  ~/tst > cat ff.txt 
  1
  2 
  3
  4
  5

Create a new git repository (repo) and add/commit the file:

  ~/tst > git init .
  Initialized empty Git repository in /home/alan/tst/.git/
  ~/tst > gits
  ?? ff.txt
  ~/tst > git add ff.txt 
  ~/tst > gits
  A  ff.txt
  ~/tst > gitcam
  [master (root-commit) 4a43178] misc
   1 file changed, 5 insertions(+)
   create mode 100644 ff.txt
  ~/tst > 

Create 2 new branches. Note that creating the branches does not mean switching to the branches:

  ~/tst > git branch aa
  ~/tst > git branch bb
  ~/tst > gitb
    aa
    bb
  * master
  ~/tst > 

Switch to branch aa and modify line 1:

  ~/tst > gitco aa
  Switched to branch 'aa'
  ~/tst > gits
   M ff.txt
  ~/tst > cat ff.txt 
  1 aa
  2 
  3
  4
  5
  ~/tst > gitcam
  [aa 10de35e] misc
   1 file changed, 1 insertion(+), 1 deletion(-)

Switch to branch bb and modify line 5

  ~/tst > gitco bb
  Switched to branch 'bb'
  ~/tst > cat ff.txt 
  1
  2 
  3
  4
  5 bb
  ~/tst > gitcam
  [bb e6d9e33] misc
   1 file changed, 1 insertion(+), 1 deletion(-)

We are still on branch bb. Merge in branch aa:

  ~/tst > git merge aa
  Auto-merging ff.txt
  Merge made by the 'recursive' strategy.
   ff.txt | 2 +-
   1 file changed, 1 insertion(+), 1 deletion(-)
  ~/tst > cat ff.txt 
  1 aa
  2 
  3
  4
  5 bb

Go back to branch aa.  Verify it is unchanged:

  ~/tst > gitco aa
  Switched to branch 'aa'
  ~/tst > cat ff.txt 
  1 aa
  2 
  3
  4
  5

Merge in the changes from branch bb.  Note we don't need to worry about getting a "double copy" of the edits to line 1:

  ~/tst > git merge bb
  Updating 10de35e..6111e93
  Fast-forward
   ff.txt | 2 +-
   1 file changed, 1 insertion(+), 1 deletion(-)
  ~/tst > cat ff.txt 
  1 aa
  2 
  3
  4
  5 bb

Verify our branches.  The * character indicates we are still on branch aa (the "aa" part will also show up in green if you are on a color terminal):

  ~/tst > gitb
  * aa
    bb
    master

So now branches aa & bb are identical.  Let's see what happens if we make identical changes on each branch and then try to merge.

Staying on branch aa, modify line 3 to be:

  ~/tst > cat ff.txt 
  1 aa
  2 
  3 xx
  4
  5 bb

Commit, then switch to branch bb & make an identical change:

  ~/tst > gitcam
  ~/tst > gitco bb
  Switched to branch 'bb'
  ~/tst > gits
   M ff.txt
  ~/tst > cat ff.txt 
  1 aa
  2 
  3 xx
  4
  5 bb
  ~/tst > gitcam
  [bb 428f3df] misc
   1 file changed, 1 insertion(+), 1 deletion(-)
  ~/tst > gitb
    aa
  * bb
    master

We are still on branch bb. Notice that git sees both branches as being identical:

  ~/tst > gitdw aa

Try merging in the changes from branch aa:

  ~/tst > git merge aa
  Merge made by the 'recursive' strategy.
  ~/tst > cat ff.txt 
  1 aa
  2 
  3 xx
  4
  5 bb

So even though the merge occurred successfully, no changes were made to the file. Git recognized that the changes were already present on each branch and did not "double apply" the change to line 3.

Let's go back to master, then merge in both branches aa & bb:

  ~/tst > gitco master 
  Switched to branch 'master'
  ~/tst > cat ff.txt 
  1
  2 
  3
  4
  5

No changes are present.  Merge in aa first:

  ~/tst > git merge aa
  Updating 4a43178..529c421
  Fast-forward
   ff.txt | 6 +++---
   1 file changed, 3 insertions(+), 3 deletions(-)
  ~/tst > cat ff.txt  
  1 aa
  2 
  3 xx
  4
  5 bb

All the changes have been merged into master.  Try merging in branch bb now:

  ~/tst > git merge bb
  Updating 529c421..b3d4ecf
  Fast-forward
  ~/tst > cat ff.txt  
  1 aa
  2 
  3 xx
  4
  5 bb

The "fast-forward" part is how git indicates that no files actually need to be merged; instead, it simply needs to "fast-forward" the branch pointer.  We see that the file is unchanged, and that the "merge" was a no-op.

We can see a list of our commits with:

  ~/tst > git log --oneline 
  b3d4ecf Merge branch 'aa' into bb
  428f3df misc
  529c421 misc
  6111e93 Merge branch 'aa' into bb
  e6d9e33 misc
  10de35e misc
  4a43178 misc

or a "graphical" picture of the commits with:

  ~/tst > git log --oneline --graph --decorate 
  *   b3d4ecf (HEAD -> master, bb) Merge branch 'aa' into bb
  |\  
  | * 529c421 (aa) misc
  * | 428f3df misc
  |/  
  *   6111e93 Merge branch 'aa' into bb
  |\  
  | * 10de35e misc
  * | e6d9e33 misc
  |/  
  * 4a43178 misc

For a better picture of the branches & merges, use the GUI tool gitk:

  > gitk

Notice that the last 3 commits have identical contents:

  ~/tst > gitdw b3d4ecf 529c421 
  ~/tst > gitdw b3d4ecf 428f3df 
  ~/tst > gitdw 529c421 428f3df

since we made identical changes to first branch aa (428f3df), then branch bb (529c421). The merged result was also the same (b3d4ecf) as both of its parents.

Viewing these results, we see that git "does the right thing" when merging multiple branches. It will not double-post identical edits made in different branches.  Also, the "master" branch is not special in any way: we could merge branches aa & bb together independently of the master branch.  

Enjoy!


Tuesday, May 26, 2015

How to Install NVIDIA Video Card Drivers for Ubuntu/Kubuntu Install or Kernel Upgrade

I have a nice new Linux computer I got from ZaReason this past Christmas, and I decided to install Kubuntu (KDE + Ubuntu) in order to more nearly match my (really slick) XPS 13 Sputnik system from Dell, which comes pre-installed with Ubuntu.  I had previously used Fedora 20 on my desktop computer, but wanted to keep the OS on both computers more in sync, and Ubuntu also has better integration with sound, video, peripherals, and other desktop (i.e. non-server) hardware concerns.

The problem is that my nice new EVGA brand video card (with NVIDIA GPU) is not natively supported by Linux, so you have to download and install the drivers from the NVIDIA website. A current driver as of this writing can be found at http://www.nvidia.com/object/unix.html (it might be easier to google "nvidia linux driver download" than to directly navigate the NVIDIA website).  Look under the "Linux x86_64" category.  I always choose the "Latest Short Lived Branch" since it will have the most bug fixes (e.g. Latest Short Lived Branch version: 349.16).  Download this file to your computer, the do a power-off restart.

The power-off part here is important. In configuring the video card, we have a fundamental conflict between the motherboard's built-in video output and the "non-standard" video card output.  When you perform a fresh Linux install or upgrade the OS kernel, you are starting from ground zero and the video card will no longer work.  Unfortunately, the Ubuntu software update system seems to come up with a semi-major patch every month or two which requires the re-installation of the video drivers. While I could avoid the problem by refusing to perform software updates, I am always eager to get bug fixes and new features in all my other packages, and I just try to minimize the inconvenience of re-installing the video card driver on the new OS kernel.

The problem is that, when the video card quits working, you can't tell what is going on, much less fix it!  The following steps are the fastest way I've found to get around these difficulties.

My video card has three (yes, count 'em, three!) video outputs, and I have become addicted to using all three monitors.  Yes, I know, it might seem excessive, but trust me:  once you've tried three monitors, you'll never (voluntarily) go back to dual monitors again.  Of course, the motherboard built-in video output makes it four video output ports in total.

Most monitors (I prefer the excellent 27 inch LG IPS 27MP65) have at least 2 inputs, both HDMI and VGA.  The trick is to use all three HDMI outputs from the NVIDIA video card to the three HDMI monitor inputs, and also connect a VGA cable from the motherboard built-in video output to one of the monitors (preferably the least-used monitor as the NVIDIA card sees it).

If only one video input is active, your monitor should normally be able to switch to the active input (HDMI or VGA) port automatically (especially when the monitor powers up).  If this sometimes fails, there should be a button labled "Input" or similar that will allow you to manually switch to the desired video input port.  Remember this, in case the monitor is displaying the VGA input and what you need to see is on the HDMI input, or vice versa.  If you find this problem is occurring, move the VGA cable to a monitor that is not trying to display HDMI.  It is much easier if you can see all active inputs simultaneously on different monitors.

When you first install Linux (or after a kernel upgrade), the new kernel will not find the drivers for the NVIDIA video card and the built-in video output will be used.  The monitor connected to the built-in VGA output should show the single-monitor display, and you'll be able to install Linux and boot up. At this point, you need to learn a few tricks.

The first trick is knowing that the NVIDIA driver cannot be installed when Linux is in the normal multi-user mode with the graphical X-Windows display active.  You must boot into a single-user, text-only mode before installing the driver.  On Kubuntu (my favorite) or plain Ubuntu this requires a power-off restart.

When booting, the GRUB bootloader will give you a 10-12 second countdown allowing you to select boot options before it attempts to auto-boot the newest kernel.  One of the options is to type the letter "e" in order to Edit the boot options.  This is what we need.  Type the "e" before the countdown timer expires.

At this point, you should see a screen such as this one:


The important part is in the lower-right-hand corner, where you can see the words "quiet splash" near the end of the next-to-the-last line.  The "quiet" part means that status messages to the console during boot are suppressed.  The "splash" part means that the OS boots into the multi-user, graphical X-Windows mode.  Both of these must be disabled in order to install the NVIDIA video driver.

Using the arrow keys, maneuver to the "quite splash" words, then use the Backspace or Delete key to remove the offending words and replace them with the single word "text".  When you are done, the screen should appear like this:


You may now follow the instructions at the bottom of the screen to continue the boot with your modified boot params (e.g. Crtl-X). You should see boot status/progress messages scrolling past on your VGA-port connected monitor.  Upon successful boot, the VGA-port monitor will look like this:


Voila!  You have booted into single-user text mode.  Go ahead & login and navigate to the directory containing the new video driver (typically ~/Downloads).

In this screen shot, you can see that I have three NVIDIA drivers downloaded (I keep forgetting to delete the older two).  Note that I don't always download the absolute most recent driver for each OS kernel update (maybe 2-3 times/year I'll download the latest driver from the NVIDIA website). Pick the newest (or only) driver you have, and invoke it as shown with "sudo bash NVIDIA-xxxxyyyyzzz.run":


While the driver is a shell script, I find it easier to invoke it using bash rather than change permissions and invoke it directly.  You need the "sudo" part since the video driver installation script must run with root permissions.  At this point, the driver will use "ASCII graphics" to complete the installation process.  It will stop about a half-dozen times to ask your permission for things.  Use the arrow keys to highlight the "Yes" answer, then hit <return> to invoke your selection.  Keep doing this until the installation is complete.

At the end of the installation, your VGA screen will be blank, and you'll be back at the command prompt.  Here, we need another power-off reboot.  Using "sudo poweroff" is a quick & easy way to do that.


Once the system has powered-off, hit the power button and begin a normal boot.  After the GRUB timer countdown, you will likely see an "Ubuntu" splash screen for a few seconds on the VGA output.  At this time, the computer should recognize your new video driver and switch to the three HDMI outputs of the video card and complete the boot process.  The VGA output will be unused from here on.

If your monitor is like mine, it may be confused by having VGA input that is active for 5-10 seconds, but then dies.  It keeps looking for the VGA input to come back and does not switch over the the (now active) HDMI input.  You can either use the monitor's Input switch to manually switch over to the HDMI input, or perform a quick power-cycle which should cause it to recognize the active HDMI input and ignore the inactive VGA input.

That's all, folks!  Happy Linuxing!

Alan Thompson

P.S.  For some cool stuff that you wish was in Clojure, you may wish to visit:  https://github.com/cloojure/cooljure     :)  

Saturday, January 3, 2015

Configuration of the LG 27MP65 (aka 27MP65HQ or 27MP65HQ-P) monitor


Configuration of the LG 27MP65 (aka 27MP65HQ or 27MP65HQ-P) monitor

I just purchased an LG 27MP65 monitor and noticed the text quality in the editor didn't seem to match up against a previous, similar LG monitor. As the new monitor was a bit higher grade, this was most surprising.

There are many menu settings that allow customization of the display.  After reading the LG manual (http://www.lg.com/us/support-product/lg-27MP65HQ-P) & playing around with them these are the best settings I've found for software development (e.g. lots of text viewing in editors).

- Turn on the monitor to start.

- Press MENU button.
  - Press DOWN button (i.e. button under downward triangle) until RESET is highlighted.
    - Press RIGHT button (i.e. button under rightward triangle) once. This will reset all
      settings to factory default (good starting point).

- Press MENU button (left-most button)
  - Press DOWN button until NEXT-MENU is highlighted. Press RIGHT button.
    - The first sub-menu is PICTURE (already selected)
      - Leave SHARPNESS at the default 5.  Lower values blur text, while higher values
        just wash it out by adding white to colors.
      - BLACK LEVEL should already be at HIGH - leave alone.
      - Always leave OVERSCAN at OFF
      - Press the "return" button (left-then-up arrow) to return to "top" menu.
  - Press RIGHT button to select COLOR. Press DOWN to select COLOR RESET on 2nd page.
    Press RIGHT to perform color reset.  Since you just did a "master" reset this should
    really be unnecessary.
      - Press the "return" button (left-then-up arrow) to return to "top" menu.
  - The remaining 3 top-level items can be ignored. Select the EXIT option.

- Just for fun, press the READER button (2nd from left).  There are 3 levels: 1, 2, OFF.
  Make sure OFF is selected it should be already).
  - Reader mode is used for e-books, etc and is not good for editing software.
  - The READER menu will disappear after a few seconds

- Press FUNCTION button (3rd from left).
  - The first sub-menu is SUPER ENERGY SAVING (already selected)
    - Press DOWN, then RIGHT to set SUPER ENERGY SAVING to OFF.
    - Press the "return" button (left-then-up arrow) to return to "top" menu.
  - Press RIGHT to select PICTURE MODE
    - Press DOWN to select PC/AV Mode. 
      - Press RIGHT until it says PC
    - Press DOWN again to the rows of modes
      - Press RIGHT to select a mode.  I have found that either TEXT or CINEMA looks best
        for GVim and GMail. Since CINEMA gives slightly better colors for
          syntax-highlighted text, that is my favorite. Your milage may vary....
      - Press the "return" button (left-then-up arrow) to return to "top" menu.
  - Press RIGHT to select SUPER RESOLUTION
    - Leave it at OFF.  Increasing this value seems to add white to all colors, simply
      making them brighter
  - The remaining 2 modes have no effect

- If you are using the DSUB (analog VGA cable) input connection, press the AUTO button
  (4th from left).  This will perform auto-tuning for the analog VGA input signal.
  - You may be happiest using an HDMI input source since it is digital
  - NOTE: Since HDMI is digital, ANY cable is just as good as any other.  It will either
    work perfectly or you will get no signal at all.  So PLEASE, don't spend $100+ on HDMI
    cables.  The $5 cables on sale are just as good.

- Just for fun, press the INPUT button (right-most button).  The display will blink
  momentarily, then verify the input source (e.g. HDMI).

- Note that the first item under the MENU button is the brightness.  If you read a lot of
  text that is black on a white background (e.g. GMail & similar), you may wish to reduce
  the brightness to 70% or some other comfortable value.
  - Don't forget that this control is still available if you need to reset the BRIGHTNESS
    to 100% for do more intense work (photo editing, watching videos, etc).