Author Archives: purpleblob

Spring boot Eureka server

Using Spring boot, we can very easily run up a Eureka server.

In IntelliJ create a new project using the Spring Initializr, simply select the Eureka Server dependency.

Once the application is create, I found I needed to add the @EnableEurekaServer annotation to the application class, so here’s my EurekatesApplication.java

package com.putridparrot.eurekatest;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer
@SpringBootApplication
public class EurekatestApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekatestApplication.class, args);
    }
}

Next we need to add the following properties to the resources/application.properties

server.port=8761

eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

logging.level.com.netflix.eureka=OFF
logging.level.com.netflix.discovery=OFF

Now when you run the application and view the web page http://localhost:8761/, you should see the Spring Eureka web page. Running http://localhost:8761/eureka/apps from your preferred browser will list any applications registered with the server.

At this point we’ve not application registered with the server, so let’s add a .NET server in the next post.

Xamarin UITest (on Android)

Having used the likes of TestStack.White in the past I was interested in trying out the Xamarin UITest library for executing tests against my mobile application’s UI.

For now I’m primarily discussing testing against an Android device or emulator, but I will amend the post as and when I run tests against iOS.

Some problems and solutions

It didn’t go smoothly, initially, getting a project running. Hence, this part of the post is going to cover some of the issues I had and some of the possible solutions.

  • If you have platform-tools.old followed by a number of digits within C:\Program Files (x86)\Android\android-sdk (for example platform-tools.old1970091580), either delete these folders or for safety’s sake, move them outside of the C:\Program Files (x86)\Android\android-sdk folder, otherwise running the UITests seems to get confused which adk it should use.
  • Add an environment variable (if not already existing) named ANDROID_HOME and set it’s value to your install of the android-sdk, i.e. C:\Program Files (x86)\Android\android-sdk
  • The version of the UITest NuGet package seems to be related to the version of the Android SDK, so after you’ve created a UITest project and added the Xamarin.UITest package, depending on the Android SDK you might need to get a previous version of this package – in my case I’m using Xamarin.UITest version 2.2.7.0 and Android SDK Tools 26.1.1
  • For an Android application, we need to set the project properties Android Manifest, Required permissions to include the INTERNET permission
  • For Android projects we need to run against a Release build
  • Again for Android projects, if we added a UITest project which include the ApplInitializer.cs file, we need to supply the application name or the path to the .apk file being used, for example
    if(platform == Platform.Android)
    {
       return ConfigureApp
          .Android
          .InstalledApp("com.putridparrot.MyApp")
          .PreferIdeSettings()
          .EnableLocalScreenshots()
          .StartApp();
    }
    

    Note: In place of InstalledApp we could use ApkFile with the path of our apk file, i.e.

       .ApkFile(@"C:\Development\MyApp\com.putridparrot.MyApp.apk")
    
  • If you’ve previously installed your application on the emulator or device, I found it best to manually uninstall it first
  • Before running your tests, make sure the emulator is running or the device is connected (I know, probably obvious)

Creating our UI test project

  • Add a Xamarin.UITest Cross-Platform Test Project to your solution
  • Build the project so it restores any missing NuGet packages, I needed to update the following packages to Xamarin.UITest version 2.2.7.0 and NUnit 3.11.0.0
  • Deploy your application to your device before running the tests
  • When running your tests, they may take a little time before you see anything happening on the emulator or device – so don’t be too impatient.

Before we can actually run our tests (which we’ll discuss next) we need to build our application and generate an APK for Android (if running against Android).

Writing our UI tests

To allow our UITests to locate controls in our user interface we supply each control (that we need to interact with) with an AutomationId, this should be unique (so it’s easy for our tests to locate).

For Android application I found this configuration works (obviously replace the ApkFile location/name with your apk).

if(platform == Platform.Android)
{
   return ConfigureApp
      .Android
      .ApkFile(@"C:\Development\MyApp\com.putridparrot.MyApp.apk")
      .PreferIdeSettings()
      .EnableLocalScreenshots()
      .StartApp();
}

Note: we should be able to replace the ApkFile line with .InstalledApp(“com.putridparrot.MyApp”) if you prefer.

The UITest project will require an AppInitializer.cs file which, if you created via the project template, will be included. Here’s an example of one

public class AppInitializer
{
   public static IApp StartApp(Platform platform)
   {
      if(platform == Platform.Android)
      {
         return ConfigureApp
            .Android
            .InstalledApp("com.putridparrot.MyApp")
            .PreferIdeSettings()
            .EnableLocalScreenshots()
            .StartApp();
     }
     return ConfigureApp
        .iOS
        .StartApp();
}

Test files (again the project template will include a Tests.cs file) might look like this

[TestFixture(Platform.Android)]
[TestFixture(Platform.iOS)]
public class Tests
{
   private IApp _app;
   private readonly Platform _platform;

   private static readonly 
      Func<AppQuery, AppQuery> LoginButton = 
         c => c.Marked("Login");

   public Tests(Platform platform)
   {
      _platform = platform;
   }

   [SetUp]
   public void BeforeEachTest()
   {
      _app = AppInitializer.StartApp(_platform);
   }

   [Test]
   public void DoesNothing()
   {
      // Arrange
      // Act
      // Assert
   }
}

Writing UI tests is much the same as writing standard unit tests, we mark our test methods with the NUnit TestAttribute, then Arrange, Act and Assert our UI. For example let’s assume we have a button with an AutomationId Login then we can create a static field within our Test class like this

private static readonly 
   Func<AppQuery, AppQuery> LoginButton = 
      c => c.Marked("Login");

This function can be used within various _app methods, such as _app.Tap(LoginButton).

As you’ve guessed I’m testing a login UI, so assuming we have a login screen with username, password and a login button we might setup our tests like this…

First Arrange our UI, for example check that we’re on the correct screen and we’ve entered a username and password. Then we’d Act by tapping the Login button then finally Assert by checking we’ve moved on from the Login screen.

REPL

When we run our tests we might want to run the _app.Repl() method which will display a REPL command line, this allows us to view the tree representing our UI.

References

Cannot run XAMARIN UI TEST on xamarin.forms, error System.Exception

The Elvis (conditional null) operator is not magic

I was looking over somebody else’s code the other day and was intrigued by the liberal use of the Elvis or correctly known as, conditional null operator, i.e. the ?.

I assumed that for every ?. the compiler would create an IF statement, but it did make me wonder whether the compiler was actually able to optimize such code (where the ?. is used multiple times on the same object), so for example, what’s produced in IL for the following

var s = ??? // null or an instance 
Console.WriteLine(s?.Name?.Length);
Console.WriteLine(s?.Name);

My assumption would be that (without any optimization) we’d end up with the following

Console.WriteLine(s != null ? (s.Name != null ? s.Name.Length : 0) : 0);
Console.WriteLine(s != null ? s.Name : null);

Or, would if magically create code like this

object o = null;
int? l = null;

if (s != null)
{
   o = s.Name;
   if (s.Name != null)
   {
      l = s.Name.Length;
   }
}

Console.WriteLine(l);
Console.WriteLine(o);

With the first snippet of code, a best case scenario results in the IF statement being called twice (when s is null), the worst case (when nothing is null) is that the IF statement will be called three times. Whereas the second example would have the IF called once (when s is null) and twice in the worst case (when nothing is null).

Ofcourse the easiest way to see what happens is to fire up ILSpy and take a look at the generated IL/C# code. Here’s the C# that ILSpy created for us based upon the IL

object obj;
if (s == null)
{
   obj = null;
}
else
{
   string name = s.Name;
   obj = ((name != null) ? new int?(name.Length) : null);
}
Console.WriteLine((int?)obj);
Console.WriteLine((s != null) ? s.Name : null);

In this code, the best case (when s is null), the IF statement is called twice and worst case (when nothing is null), it’s called three times.

This is a simple example, but it’s worth being aware of what code is being produced using such syntactic sugar.

Solution specific NuGet repository locations

Whether we’re making our code available to others or want to simply implement solution specific changes to our NuGet repository locations, we can create a NuGet.config file which is stored in the same location as our solution. Here’s a simple example of a NuGet.config which adds a local NuGet location

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <packageSources>
       <add key="Local" value="c:\Development\LocalNuGet" />
    </packageSources>
</configuration>

References

Configuring NuGet behavior

Tasks and CancellationTokens

We’re executing some code on a background thread using the Task API, for example let’s create a really simple piece of code where we loop on a task every second and call UpdateStatus to display the current iteration to some UI control, such as this

Task.Factory.StartNew(() =>
{
   for (var i = 1; i <= 100; i++)
   {
      UpdateStatus(i.ToString());
      Thread.Sleep(1000);
   }
});

Now this is fine, but what about if we want to call this code multiple times, stopping any previous iterations or we simply want a way to cancel the thread mid-operation.

Cancellation is a co-operative process, i.e. we can call the Cancel method on a CancellationTokenSource but we still need code within our task’s loop (in this case) to check if cancel has been called and then exit the loop.

The cancellation token is actually taken from CancellationTokenSource which acts as a wrapper for a single token (see References for information about this separation of concerns). So in our class we’d have the following member field

private CancellationTokenSource _cancellationTokenSource;

If the code which uses this token is called prior to completion then we’d potentially want to call the Cancel method on it and then dispose of it.

_cancellationTokenSource.Cancel();
_cancellationTokenSource.Dispose();

As mentioned, the separation of the token source and token means that when we execute a task we pass, not the token source, but a token take from the source, i.e.

var cancellationToken = _cancellationTokenSource.Token;
Task.Factory.StartNew(() =>
{
   // do something
}, cancellationToken);

The final piece of using the cancellation token is within our task, where we need to check if the cancellation token has been cancelled and if so, we can throw an exception using the following

cancellationToken.ThrowIfCancellationRequested();

Here’s a very simple example of using the cancellation token

public partial class MainWindow : Window
{
   private CancellationTokenSource _cancellationTokenSource;

   public MainWindow()
   {
      InitializeComponent();
   }

   private void Start_OnClick(object sender, RoutedEventArgs e)
   {
      DisposeOfCancellationTokenSource(true);

      _cancellationTokenSource = new CancellationTokenSource();
      var cancellationToken = _cancellationTokenSource.Token;

      UpdateStatus("Starting");
      Task.Factory.StartNew(() =>
      {
         for (var i = 1; i <= 100; i++)
         {
            cancellationToken.ThrowIfCancellationRequested();

            UpdateStatus(i.ToString());

            Thread.Sleep(1000);
         }
      }, cancellationToken)
      .ContinueWith(ca =>
      {
         DisposeOfCancellationTokenSource();
      }, TaskContinuationOptions.OnlyOnFaulted);
   }

   private void UpdateStatus(string status)
   {
      Status.Dispatcher.Invoke(() => Status.Content = status);
   }

   private void DisposeOfCancellationTokenSource(bool cancelFirst = false)
   {
      if (_cancellationTokenSource != null)
      {
         if (cancelFirst)
         {
            _cancellationTokenSource.Cancel();
            UpdateStatus("Cancel called");
         }
         _cancellationTokenSource.Dispose();
         _cancellationTokenSource = null;
         UpdateStatus("TokenSource Disposed");
      }
   }

   private void Stop_OnClick(object sender, RoutedEventArgs e)
   {
      DisposeOfCancellationTokenSource(true);
   }
}
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Button Grid.Row="0" Content="Start" Margin="10" Click="Start_OnClick"/>
        <Button Grid.Row="1" Content="Stop" Margin="10" Click="Stop_OnClick"/>
        <Label Grid.Row="2" Name="Status" Content=""/>
    </Grid>

References

Why CancellationToken is separate from CancellationTokenSource?
Task Cancellation
CancellationTokenSource.Dispose Method

Java’s Linq equivalent, Streams

I was working on a previous post on Java and GraphQL and wanted to use a Linq query. Java doesn’t have Linq but it does have something equivalent (in Java 8) called Stream. For the examples within this post we’ll create the following simple method for generating our test data

private static List<String> getData() {
   return Arrays.asList(
      "2", "2", "2", "4", "4", 
      "6", "7", "7", "9", "10");
}

Let’s look at some of the standard sort of functionality…

Distinct

We can get a distinct stream from our data using

Stream<String> distinct = getData()
   .stream()
   .distinct();

Selection/Filtering

If we want to filter our data to select only strings longer than one character, for example, then we can use the following

Stream<String> where = getData()
   .stream()
   .filter(s -> s.length() > 1);

Matching

There are several methods which return a Boolean, for example if all items in the Stream are of a certain value, or any of the values no matches, for example

boolean allMatch = getData()
   .stream()
   .allMatch(s -> s.contains("4"));

boolean anyMatch = getData()
   .stream()
   .anyMatch(s -> s.contains("4"));

boolean noneMatch = getData()
   .stream()
   .noneMatch(s -> s.contains("4"));

Map

In scenarios where we wish to change the data returned from a stream (i.e. like Select in Linq), for example we’ll simply loop through each item and return the length of each string as a Stream, we can use

Stream<Integer> select = getData()
   .stream()
   .map(String::length);

Reduce

If we want to take a stream and reduce it to a single value, for example taking our data and concatenating into a single String, we could use the following

String reduce = getData()
   .stream()
   .reduce("", (a, b) -> a + b);

The initial value “” in this case is a starting value for the reduced value, in this case we’re not wanting to prepend anything to our string. The result of the reduce is a String with the value 22244677910.

Creating an empty Stream

We can create an empty Stream (useful in those situations where we do not wish to return a null) using

Stream<String> empty = Stream.empty();

Iteration

We can iterate over the Stream using the forEach method, for example

getData()
   .stream()
   .forEach(s -> System.out.println(s));

Parallel Streams

We can also parallelize (is that a word) our Stream using the parallelStream, for example

Stream<Integer> parallel = getData()
   .parallelStream()
   .map(String::length);

As you’d expect the order or processing of the map in this instance is indeterminate.

Obviously there’s more to Stream than I’ve listed here, but you get the idea.

Creating a TaskScheduler

In my previous post, ExecutorService based multi-threading in Java, I looked at the ExectorService which allows us to create our own fixed size threadpool which can, at times, be extremely useful.

As part of a port of some Java code (which used the ExectorService) to C# I had a need for a similar class in .NET and came across the LimitedConcurrencyLevelTaskScheduler which is part of the Samples for Parallel Programming with the .NET Framework. The code and example of this class can also be found here, TaskScheduler Class.

The Task factory’s StartNew method comes with an overload which takes a TaskScheduler class and this is where the LimitedConcurrencyLevelTaskScheduler is used. For example

var taskScheduler = new LimitedConcurrencyLevelTaskScheduler(3);
var tsk = Task.Factory.StartNew(() =>
{
   // do something
}, 
CancellationToken.None, 
TaskCreationOptions.None, 
taskScheduler);

So, if we’re in a situation where we need to create a new TaskScheduler then we simply implement a TaskScheduler class, here’s the required overrides.

public class MyTaskScheduler : TaskScheduler
{
   protected override IEnumerable<Task> GetScheduledTasks()
   {
   }

   protected override void QueueTask(Task task)
   {
   }

   protected override bool TryExecuteTaskInline(
      Task task, bool taskWasPreviouslyQueued)
   {
   }
}

The QueueTask method is called when a Task is added to the scheduler. In the case of an implementation such as LimitedConcurrencyLevelTaskScheduler, this is where we add a task to a queue prior to executing the task.

TryExecuteTaskInline is called when trying to execute a task on the current thread, it’s passed a Boolean taskWasPreviouslyQueued which denotes whether the task has already been queued.

GetScheduledTasks is called to get an enumerable of the tasks currently scheduled within our TaskScheduler.

Optionally, we may wish to override the MaximumConcurrencyLevel property which stipulates the maximum concurrency level supported (i.e. number of threads), the default is MaxValue. Also where we might be maintaining a queue of tasks, we wold want to override the TryDequeue method for when the scheduler tries to remove a previously scheduled task.

Obviously implementing the TaskScheduler will also require the developer to handle any thread synchronization etc. within the implementation.

ExecutorService based multi-threading in Java

A threading feature within Java is the ExecutorService. This allows us to, in essence, create our own threadpools. This is useful because it allows us to create a limited number of threads that our code may run on, ensuring we do not end up with thread starvation or the number of threads getting out of hand.

By writing our code to use the ExecutorService we can also limit our methods to only use a single thread if we want.

Here’s a simple example of using the ExectorService

public static void main(String[] args) throws 
   InterruptedException, 
ExecutionException {

   System.out.println("Main Thread - " + Thread.currentThread().getId());

   //ExecutorService executorService = Executors.newSingleThreadExecutor();
   ExecutorService executorService = 
      Executors.newFixedThreadPool(
         Runtime.getRuntime().availableProcessors());

   Future<?> f1 = executorService.submit(() 
      -> outputInformation(1));
   Future<?> f2 = executorService.submit(() 
      -> outputInformation(2));
   Future<?> f3 = executorService.submit(() 
      -> outputInformation(3));

   // the equivalent of waiting on the threads
   f1.get();
   f2.get();
   f3.get();

   executorService.shutdown();
}

private static void outputInformation(int id) {
   try {
      // some arbitrary time wasting
      Thread.sleep(2000);
      System.out.println(id + " - " + Thread.currentThread().getId());
   }catch (Exception e) {
   }
}

In the code above, we are creating our own threadpool (using Executors.newFixedThreadPool) with the size based upon the number of available processors. Hence in this example (assuming you have more than 1 processor on your machine) the resulting output is indeterminant, i.e. we might see 2 followed by 1, followed by 3 and all on different threads.

By simply changing to use Executors.newSingleThreadExecutor() the output will be in the correct order as only a single thread is used for each call.

The ExecutorService is a useful abstraction for containing and controlling multiple threads.

Spring boot and GraphQL

A previous post Writing a GraphQL service using graphql-dotnet and ASP.NET core covered implementing an ASP.NET application with a GraphQL service.

As GraphQL is language/platform agnostic I wanted to see how to implement a similar little service using Java frameworks.

I’m using JetBrains’ IntelliJ (I think you need the ultimate edition for this) to create a project, so I’ll list a few steps regarding this process. In IntelliJ

  • Create a new Project
  • Select Spring Initializr
  • Leave the defaults as https://start.spring.io and just press the Next button
  • Supply a name for your project then press the Next button
  • At the next page you can select dependencies, just press the Next button
  • Finally give your project a name then press the Finish button

Now let’s update the pom.xml with the following

<!-- Add the following for GraphQL -->
<dependency>
   <groupId>com.graphql-java</groupId>
   <artifactId>graphql-spring-boot-starter</artifactId>
   <version>5.0.2</version>
</dependency>
<dependency>
   <groupId>com.graphql-java</groupId>
   <artifactId>graphql-java-tools</artifactId>
   <version>5.2.4</version>
</dependency>

<!-- Add this for the GraphQL interactive tool -->
<dependency>
   <groupId>com.graphql-java</groupId>
   <artifactId>graphiql-spring-boot-starter</artifactId>
   <version>4.0.0</version>
</dependency>

As shown with the comments, the last dependency will allow us to include the GraphQL interactive web application graphiql, obviously remove this if you do not need it.

Now let’s write some code…

Schema and Queries

Unlike the previous C# example, we’re going to use the GraphQL schema definition language to declare our schema (in C# we used code to implement this).

In your package folder add Person.java with the following code

public class Person {
    private String name;

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

It’s basic but this is our starting point (and matches what we did in the C# example).

We now need to create a QueryResolver, so add a file named Query.java to the package with the following code

import com.coxautodev.graphql.tools.GraphQLQueryResolver;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
public class Query implements GraphQLQueryResolver {
    List<Person> people = new ArrayList<>();

    public Query() {
        people.add(new Person("Scooby"));
        people.add(new Person("Shaggy"));
        people.add(new Person("Daphne"));
        people.add(new Person("Thelma"));
        people.add(new Person("Fred"));
    }

    public List<Person> people() {
        return people;
    }
}

That’s it for the Java code for now – Spring Boot’s dark magic will wire everything up for us, but before then we need to add a .graphqls file. Within the resources folder lets add a schema file named schema.graphqls (IntelliJ comes with a plugin for recognising this file type).

Note: the name of the file need not be schema, any name will suffice for this example.

Within the schema.graphqls file we have the following

type Query {
    people : [Person]
}

type Person {
    name: String!
}

That’s it!

Running the application will result in a Tomcat embedded server running on http://localhost:8080/graphiql (assuming you include graphiql in the Maven file). If we now execute the following query within graphiql

{
  people {
    name
  } 
}

we should see the result

{
  "data": {
    "people": [
      {
        "name": "Scooby"
      },
      {
        "name": "Shaggy"
      },
      {
        "name": "Daphne"
      },
      {
        "name": "Thelma"
      },
      {
        "name": "Fred"
      }
    ]
  }
}

Let’s now add an operation find to allow us to locate a Person by their name. In the Query class, add the following

public Person find(String input) {
   return people.stream()
      .filter(p -> p.getName().equalsIgnoreCase(input))
      .findFirst()
      .orElse(null);
}

This code acts a little like a Linq query in C#, returning an Optional, we’ll basically return a null if no item was found hence unwrapping our return from the Optional.

We need to add this operation to the schema.graphql Query type, so it now looks like this

type Query {
    people: [Person]
    find(input: String!) : Person
}

Running the application we can now write the following in graphiql

{
   find(input : "Scooby") {
      name
  }
}

Mutations

Next up, let’s write a mutation to add a person. We’re not going to add a Person to the list of people as this would require some refactoring of the query data, but it simply demonstrates the changes required to our project to implement mutations.

Let’s jump into the schema file and add mutation to the schema definition, so it looks like this

schema {
    query: Query
    mutation: Mutation
}

and now add the mutation type into the file, which should look like this

type Mutation {
    addPerson(input: String) : Person
}

Now we’ll create the code. Add a file (mine’s called Mutation.java) for our mutation code, here’s a the very simple example

import com.coxautodev.graphql.tools.GraphQLMutationResolver;
import org.springframework.stereotype.Component;

@Component
public class Mutation implements GraphQLMutationResolver {
    public Person addPerson(String input) {
        return new Person(input);
    }
}

That’s all there is to it, run the application and using grapiql, write the following in your query window

mutation addPerson($input : String) {
   addPerson(input : $input)
   {
      name
   }
}

and in the Query variables window add the following

{
  "input" : "Scooby Doo"
}

Subscriptions

Finally let’s write some subscription code. Change the schema.graphqls schema to look like this

schema {
    query: Query
    mutation: Mutation
    subscription : Subscription
}

and add the following type

type Subscription {
    personAdded : Person
}

The Subscription.java file will look like this

import com.coxautodev.graphql.tools.GraphQLSubscriptionResolver;
import org.reactivestreams.Publisher;
import org.springframework.stereotype.Component;

@Component
public class Subscription implements GraphQLSubscriptionResolver {

    private PersonPublisher publisher;

    public Subscription(PersonPublisher publisher) {
        this.publisher = publisher;
    }

    public Publisher<Person> personAdded() {
        return publisher.getPublisher();
    }
}

This implements our Subscription resolver, but we’ll separate out the publisher code to look like this. Here’s my PersonPublisher.java file

import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.Observable;
import io.reactivex.observables.ConnectableObservable;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;

@Component
public class PersonPublisher {

    private final Flowable<Person> publisher;

    public PersonPublisher() {
        Observable<Person> o = Observable.interval(1, 1, TimeUnit.SECONDS)
                .map(l -> new Person(l.toString()));
        ConnectableObservable<Person> co = o.share().publish();

        publisher = co.toFlowable(BackpressureStrategy.BUFFER);
    }

    public Flowable<Person> getPublisher() {
        return publisher;
    }
}

Note: I’ve based the code for the Subcription and PersonPublisher on the Subscription.java and the StockTickerPublisher.java sample code.

Code

Code is available on GitHub.

Disclaimer

graphiql does not display subscription events at this time. So I’ve not tested this subscription code. Hence beware, it may or may not work. I’ll try to update when I get chance to test it fully.

Git aliases

In a previous post on git (Using GIT from the CLI), I listed a fair few commands which are very useful. For the most part they’re fairly simple commands/options, but occasionally they become less easy to remember.

For example to check for merge conflicts on a branch that you may wish to merge master to, you can type

git merge master --no-ff --no-commit

Luckily I have this blog post allowing me to copy and paste this command, an alternate might be to create an alias to this command.

Adding an alias

Creating the alias is simply a way to store a command name within git’s global config which runs another command. Whether we want to simply shorten a name, like using co and ci in place of checkout and commit or shorten a command such as the merge above with check-conflicts.

To create an alias we use the following

git config --global alias.check-conflicts 'merge master --no-ff --no-commit'

In this example we’re telling git to add configuration using –global option (so the configuration is across all repositories or –local for just this repository). We create the alias using the alias option followed by a period/full stop and then the name we want for our alias. This is then followed by the git command and options (within single or double quotes if there are multiple options).

Now we can execute

git check-conflicts

Deleting an Alias

To delete an alias we can either remove it from the config file (for example .gitconfig) or run the following command line

git config --global --unset alias.check-conflicts

Listing Aliases

We can look in the .gitconfig or run the following command line to list the available aliases

git config --get-regexp '^alias\.'

Creating an Alias to list Aliases

To round this up nicely, let’s now create an alias to list aliases, for example

git config --global alias.alias "config --get-regexp ^alias\."