Monday, September 19, 2016

Clone a Git Repository Into a Specific Folder

Let's take a look at a sample git repository URL:
https://github.com/apolunin/java8-impatient
It can be cloned via the following command:
git clone https://github.com/apolunin/java8-impatient
The contents of the repository will be put in the 'java8-impatient' folder which will be created in a current working directory. What if we want a different one? Fortunately this is very easy to do in Git. Here is a quick but useful tip which shows how to clone a Git repository into a different folder:
git clone https://github.com/apolunin/java8-impatient my-impatient-repo
This time the contents of the repository will be put in the 'my-impatient-repo' folder under the current working directory.

Change File Type in Vim

Recently I had to write a few lines of code in assembly language. Vim and GAS were chosen as suitable tools to use. I downloaded vim-gas plugin, installed it using vim-plug (Vim plugin manager that I prefer) and started coding. Unfortunately Vim detected file type as 'vmasm' by default, not as 'gas', so syntax highlighting was incorrect. In this post I describe several solutions to this problem.

Set File Type Manually

The first obvious solution which comes to mind is to set file type manually. This can be done via the following Vim command:
:set filetype=gas
This definitely works, but setting the file type manually every time it is opened seems awkward and impractical. Fortunately there are better alternatives.

Override File Type Using Auto Commands

There are several automatic commands (autocmd) which can be added to .vimrc in order to set file type:
au BufRead,BufNewFile *.s   setfiletype gas
au BufRead,BufNewFile *.s   set filetype=gas
The first option didn't work for me, because it is used to set the file type only if it hasn't been detected yet. As I mentioned earlier, in my case file type was detected as 'vmasm'.

The second option worked as expected and Vim detected the file type as 'gas'.

Override File Type Using Modelines

Another way to influence Vim filetype detection is to use modelines. Looks like the modelines are disabled by default. In order to turn them on the following lines should be added to .vimrc:
set modeline
set modelines=5
The first line enables modelines and the second one sets the max number of modelines which Vim takes into account. Look at the Vim docs for more details.

The following modeline can be added to the *.s file in order to help Vim to detect file type as 'gas':
/* vim: set filetype=gas: */
Apparently modelines approach requires adding a special line in every *.s file while autocmd approach can be configured solely in .vimrc. So I decided to stick to the latter which suits my needs just fine.

That's all there is to it.
Thanks for reading!

Wednesday, May 25, 2016

Convert InputStream to String in Java

Sometimes in Java world it is necessary to convert an InputStream to a String for further processing. There are several ways to do it, but here is a fantastic trick I recently discovered in this article:
final String text = new Scanner(inputStream)
        .useDelimiter("\\A").next();
The idea behind this trick is regex \A. It matches the beginning of input. Since there is only one beginning of input the whole contents of the stream is returned as the first (and the last) token.

There is a problem with the code above. It would throw an exception if the provided stream is empty. However this is easy to fix:
final Scanner scanner = new Scanner(inputStream)
        .useDelimiter("\\A");
final String text = scanner.hasNext() ? scanner.next() : "";
If a specific charset must be used it could be passed as the second argument to the Scanner constructor:
final Scanner scanner = new Scanner(inputStream, "ISO-8859-1")
        .useDelimiter("\\A");
final String text = scanner.hasNext() ? scanner.next() : "";
That's all there is to it.
Thanks for reading!

Friday, April 22, 2016

Create a GUID in Java

Some software development tasks need a way to generate unique identifiers. I saw several homegrown solutions, but Java 5 makes the process a breeze. It contains class UUID which can generate type 4 (pseudo randomly generated) unique identifiers. Here is a simple example:
package net.softwaregeek;

import java.util.UUID;

public class UUIDMain {
    public static void main(final String[] args) {
        System.out.println(UUID.randomUUID());
    }
}
The code is self-explanatory. It generates a unique identifier and prints it to console. Class UUID contains several other useful methods which I encourage you to explore on your own.

Thursday, April 7, 2016

Change Editor for Git Commit Messages

Git is a very powerful tool especially when used from a console. Obviously committing changes is a pretty common task which includes editing commit messages. If a message is short it is easy to specify it via -m option:
$ git commit -m "my commit message"
But what if you have a long list of changes and you need a descriptive well-formatted commit message? It would be cool to write it in your favorite text editor, wouldn't it? Is there a way to tell Git which editor to use? Yes, it is. According to the docs for git-commit:

"The editor used to edit the commit log message will be chosen from the GIT_EDITOR environment variable, the core.editor configuration variable, the VISUAL environment variable, or the EDITOR environment variable (in that order)."

I'm a Vim fan and I stick to the core.editor configuration variable. So, here is my preferred way to configure commit message editor:
$ git config --global core.editor "vim"
Now I can omit -m option and enjoy editing commit messages in Vim :)

Wednesday, April 6, 2016

Rename a Remote Branch in Git

In the previous post I described how to rename a local branch in Git. Now let's take a look how to rename a remote branch. The process is a bit more complicated than with a local one and consists of the following steps:
  1. Create a new local auxiliary branch with the desired name.
  2. Push newly created local branch to the remote repository.
  3. Delete the original branch from the remote repository.
  4. Delete an auxiliary local branch (optional).
Let's take a look at a simple example. Suppose I have a Git repository which contains a couple of remote branches in it:
$ git branch -r
  origin/HEAD -> origin/master
  origin/master
  origin/release-v1.0
Suppose that branch release-v1.0 was created by mistake and I actually want it to be named release-v1.1. Let's perform the first step and create an auxiliary branch:
$ git branch release-v1.1 origin/release-v1.0
Let's see what we have locally and remotely:
$ git branch
* master
  release-v1.1
$ git branch -r
  origin/HEAD -> origin/master
  origin/master
  origin/release-v1.0
Now it is time to push our new local branch to the remote repository:
$ git push origin release-v1.1
The above command creates a new remote branch named after the local one created on the previous step:
$ git branch -r
  origin/HEAD -> origin/master
  origin/master
  origin/release-v1.0
  origin/release-v1.1
Let's delete the old remote branch:
$ git push origin :release-v1.0
Now we have the following remote branches:
$ git branch -r
  origin/HEAD -> origin/master
  origin/master
  origin/release-v1.1
Optionally we can get rid of the auxiliary local branch:
$ git branch -d release-v1.1
Let's take a look at the final result:
$ git branch
* master
$ git branch -r
  origin/HEAD -> origin/master
  origin/master
  origin/release-v1.1
Here are all the commands in one place for convenience:
$ git branch release-v1.1 origin/release-v1.0
$ git push origin release-v1.1
$ git push origin :release-v1.0
$ git branch -d release-v1.1

Rename a Local Branch in Git

From time to time I have typos crept in the names of Git branches I create. Certainly it is possible to delete a branch and create a new one with corrected name. However Git allows for combining two steps into a single one. Here is a simple way to rename a local branch:
git branch -m <old-branch-name> <new-branch-name>
If a branch which should be renamed is the current one then the command above can be further simplified to the following:
git branch -m <new-branch-name>
If a branch named <new-branch-name> already exists -M option (which is actually just a shortcut for -m -f) can be used to force rename:
git branch -M <old-branch-name> <new-branch-name>
Type in the following command to get more information:
git help branch