Blog 1

Random Talk on Random Thoughts

Git Merge Failed?

| Comments |

Problem

Octopress has recently removed Rubypants, so the automatic smartquotes aren’t supported any more. However, after typing git pull octopress master on the source branch of the local working directory for this blog, git simply said that it’s “already up-to-date”. I compared the stored trees for plugins/ by using git show HEAD:plugins on the source and octopress/master branches. If the former has the commits of the later, then plugins/rubypants.rb shouldn’t be found on the former. I issued the command git merge octopress/master again, and the version control system still said that there’s no unmerged commits from the octopress/master branch.1

Rare Sed Delimiters

| Comments |

Background

One can replace the usual delimiter / in sed with the other ones. Therefore, the slashes in the URL inside the search pattern won’t have to be escaped by backslashes, which makes the whole command ugly.

Problem

If the search pattern contains multiple characters like ;, #, |,   (white space), etc, and you’re too lazy to look for other choices of delimiters, what can you do?

Find Files for Vim to Edit in Bash

| Comments |

Background

Since copying and pasting the output of a command can be a tedious job. For example, if you want to create your blog using a framework, you may first logon to your GitHub account and create an empty repository there, then git clone Octopress/Jekyll-Bootstrap from GitHub, reset the origin URL, and input the new URL based on the old one.

After having created a repository online, you will see the URL of the repository using the SSH protocol. If one doesn’t want to repeat the start of the URL git@github.com:, one may use the bash commands introduced in the previous post to extract its useful parts for the sed substitution.

$ git remote -v
octopress	git@github.com:imathis/octopress.git (fetch)
octopress	git@github.com:imathis/octopress.git (push)
origin	git@github.com:VincentTam/vincenttam.github.io.git (fetch)
origin	git@github.com:VincentTam/vincenttam.github.io.git (push)
$ name=userName; repo=repoName
$ git remote -v | sed -n '3{p;q}' | awk '{print $2}' | sed -r \
"s;(\w*)/(.*).git;$name/$repo.git;"
$ unset name repo

Problem

I tried extracting a list of Markdown files containing a particular word and passing them to Vim as arguments using find, grep and xargs. Unluckily, I got an error.

$ find source/_posts/ -name "*.markdown" -exec grep -q ^tag {} \; \
> -print | xargs vi
Vim: Warning: Input is not from a terminal
3 files to edit
$ 

Note: Without the -print flag, the above command won’t work.

Upgrade to Java 8 on Ubuntu 14.04

| Comments |

Background

Before writing the previous post, I had noticed that the version number of the current stable release of Java is 1.8 update 51.

Method

  1. Google “ubuntu 14.04 java 8”.
  2. Click on the first search result.
  3. Follow the instructions there.

    Note that the command in the section “Configuring Java Environment” should be run before the one in “Verify Installed Java Version”.1

Lessons learnt

The encoding of files can be converted using iconv.


Debug Apps on Real Devices in Android Studio

| Comments |

After spending hours to find out that I need to tap on “Settings” → “About” → … → “Build number” for enabling USB debugging in the “Developers options” on an Android phone, I plugged the phone into a Mac desktop, but it didn’t show up in the “Devices” in Finder. I thought that Mac couldn’t detect the phone, and I searched Google for a long time. After having seen the name of an application for synchronising data between and phone and the computer for a few times, I finally decided to download it since I didn’t know what else to do. Luckily, my app could be run on the phone with the help of Android Studio installed on the Mac desktop.

An hour later, I tried to setup the development environment on an M$ Win* computer. Its installed size is over 20GB! After hours of installation work, I was stuck again on M$ Win*: unlike the Mac computer, that M$ Win* machine could detect the Android mobile device and show it in “Computer” within a minute. I added the following lines into /{AppName}/app/build.gradle according to a page of the official website.

To enable debugging on a real Android device
1
2
3
4
5
android {
    buildTypes {
        debug {
            debuggable true
        }

However, the IDE said that no debuggable device could be found. I guessed that the synchronising application made by the manufacturer of the phone was the cause of that undesirable result. After fetching the application from the website of the phone manufacturer and restarting Android Studio, I could finally run the same application on a real Android device by clicking the little triangle on the top.

Git Object ID Generation (5): Predict ID

| Comments |

Goal

The method for getting the Git object ID described in previous post in this series isn’t quick enough since it consists of several commands.

The one-line command

Objects with known Git ID

$ (printf "{obj_type} $(git cat-file -s {hash})\0" && git cat-file {obj_type} {h
ash}) | shasum
  • {obj_type} can be blob, tree, commit or tag.
  • {hash} is the SHA-1 hash of the object.

Then the output SHA-1 hash should be the same as the input {hash}.

Predict Git object IDs

Hence, we can modify the above command to predict the Git object ID of a {file}.

$ (printf "{obj_type} $(wc -c {file} | tr -dc '0-9')\0" && cat {file}) | shasum

In order to verify the result for files, one can quickly get the blob ID from Git by git log -1 -p -- {file}.

Facts learnt

Extract numbers from a string in bash

I typed “linux extract number” on Google, and the autocompletion gave me “from string”. I finally saw two commands for doing this.

  1. sed 's/[^0-9]//g'
  2. tr -dc '0-9'

In my opinion, the later is simpler. The -c flag takes the complement of the characters marked by -d.

Using cat on M$ Win*

Using the command in the section “Predict Git object IDs” gives users a wrong SHA-1 sum. The reason is that M$ Win* uses \r\n instead of \n for starting newlines. This also results in the incorrect byte count of the files with \r\n as the line terminator in that command. Thus, the extra \r needs to be deleted with tr -d '\r'.

Using Git for Win*

For the installed version of Git on M$ Win*, one needs to use sha1sum instead of shasum. Otherwise, Git Bash will complain that it is “Unable to find Digest::SHA or Digest::SHA::PurePerl”.

Using GitPortable on M$ Win*

Since one can’t even issue the command sha1sum, use openssl sha1 instead. (Omitting the trailing 1 will result in a very different hexadecimal number.)

Git Object ID Generation (4): General Trees

| Comments |

Background

After I’ve written the third post in this series, I believed that I could generate the SHA-1 hash of all Git objects.

Problem

In order to understand the object ID of an arbitrary tree object, it is necessary that I create a file in a sub-folder. Suppose that I copied the file hello.txt to the sub-directory subdir in the directory hello in the second post In short, I just followed the steps in Chapter 4 of Version Control with Git. I include the setup here for convenience.

$ mkdir hello && cd hello
$ git init
$ echo "hello world" > hello.txt
$ git add hello.txt
$ git write-tree
68aba62e560c0ebc3396e8ae9335232cd93a3f60
$ mkdir subdir
$ cp hello.txt subdir
$ git add subdir/hello.txt
$ git write-tree
492413269336d21fac079d4a4672e55d5d2147ac
$ git cat-file -p 492413269336d21fac079d4a4672e55d5d2147ac
100644 blob 3b18e512dba79e4c8300dd08aeb37f8e728b8dad	hello.txt
040000 tree 68aba62e560c0ebc3396e8ae9335232cd93a3f60	subdir

After having successfully generated the SHA-1 hash for the tree object 68aba62e560c0ebc3396e8ae9335232cd93a3f60 in the second post in this series, I tried the same task for another tree object 492413269336d21fac079d4a4672e55d5d2147ac. Using the same technique describe in the previous post, I got another wrong SHA-1 hash 06eb95bda67a8f86e65bb1590744f10a61eeccef.

# Note: I *didn't* type enter in the following command.  Just keep typing.
$ printf "tree 71\x00100644 hello.txt\x00\x3b\x18\xe5\x12\xdb\xa7\x9e\x4c\x83\x0
0\xdd\x08\xae\xb3\x7f\x8e\x72\x8b\x8d\xad040000 subdir\x00\x68\xab\xa6\x2e\x56\x
0c\x0e\xbc\x33\x96\xe8\xae\x93\x35\x23\x2c\xd9\x3a\x3f\x60"
06eb95bda67a8f86e65bb1590744f10a61eeccef  -

How to get the right object ID?

Git Object ID Generation (3): Trees With Multiple Blobs

| Comments |

Background

Having written the second post in this series, I thought that I understood how to compute the SHA-1 hash of Git tree objects.

Problem

Suppose that I add a file named rose which consisted merely of the word sweet and a line terminator to the folder hello in the second post in this series. I include the setup here for convenience.

$ mkdir hello && cd hello
$ git init
$ echo "hello world" > hello.txt
$ git add hello.txt
$ git write-tree
68aba62e560c0ebc3396e8ae9335232cd93a3f60
$ echo "sweet" > rose
$ git add rose
$ git write-tree
b12767ff2f8a8160bca15abfb775bca5ba31ccf1
$ git cat-file -p b12767ff2f8a8160bca15abfb775bca5ba31ccf1 | tee test.txt
100644 blob 3b18e512dba79e4c8300dd08aeb37f8e728b8dad    hello.txt
100644 blob aa823728ea7d592acc69b36875a482cdf3fd5c8d    rose

Therefore, our target hash is b12767ff2f8a8160bca15abfb775bca5ba31ccf1.

Just like what I’d done in the previous post, I manually changed the hashes into a printf command that writes out the binary value of the hashes.

# Note: I *didn't* type enter in the following command.  Just keep typing.
$ printf "tree 70\x00100644 hello.txt\x00\x3b\x18\xe5\x12\xdb\xa7\x9e\x4c\x83\x0
0\xdd\x08\xae\xb3\x7f\x8e\x72\x8b\x8d\xad\n100644 rose\x00\xaa\x82\x37\x28\xea\x
7d\x59\x2a\xcc\x69\xb3\x68\x75\xa4\x82\xcd\xf3\xfd\x5c\x8d" | shasum
a4b430f9da3e22c0854fb26c97da77db271e5acf  -

What I got is a4b430f9da3e22c0854fb26c97da77db271e5acf, which is different from the target. How can I get back the right SHA-1 hash?

Git Object ID Generation (2): Trees With One Single Blob

| Comments |

Background

In the first post in this series, I’ve claimed that the generation of object IDs in Git is the SHA-1 hash of the string

<object type name> SP <len> NUL <data>

,where

  • <data> stands for the output of git cat-file -p {hash}
  • <len> means the length of <data>. It can be measured with the command wc -c.

Problem

To verify my claim, I followed the steps in Chapter 4 of Version Control with Git.

  1. Create a folder named hello and go to that directory.
  2. Initialise an empty Git repository.
  3. Create the file hello.txt with one single line “hello world”.
  4. Add the file to Git’s object storage.
  5. Get a tree object from the index.
  6. Capture the contents of the tree object in test.txt.
  7. Count the number of bytes in test.txt.
  8. Create the file len.txt consisting of

     "tree" SP <result in item 6> NUL
    

    without the line terminator.

  9. Concatenate the contents of the files len.txt and test.txt and compute its SHA-1 hash.
$ mkdir hello && cd hello
$ git init
$ echo "hello world" > hello.txt
$ git add hello.txt
$ git write-tree
68aba62e560c0ebc3396e8ae9335232cd93a3f60
$ git cat-file -p 68aba62e560c0ebc3396e8ae9335232cd93a3f60 | tee test.txt
100644 blob 3b18e512dba79e4c8300dd08aeb37f8e728b8dad	hello.txt
$ wc -c test.txt
63 test.txt
$ printf "tree 63\0" > len.txt
$ cat len.txt test.txt | shasum
10bd0f0350027c25edc4ce72aba60e641f55596d  -

As can be seen above, I’ve a wrong SHA-1 hash. How can I get back the right SHA-1 hash?