Code documentation

Development Tools

Code Structure

Techniques and Standards

Help and Web Site

How To

Functional Info

Background Info

JMRI Help:
Contents/ Index
Glossary/ FAQ

Donate to JMRI Donate to JMRI.org

JMRI: Using GitHub Desktop

First some useful definitions:
Git:
A version control system, used by the developers of JMRI
GitHub:
A web site and a host for projects using Git
GitHub Desktop:
A graphical front end for Git.
Before using GitHub Desktop, we need to fork the JMRI repository to our own repository. For this, we log in to https://github.com/ , go to the JMRI repository https://github.com/JMRI/JMRI and click the button "Fork" on the top right side of the GitHub web site.

We then start GitHub Desktop. We now need to clone our JMRI repository to the local computer.



This tutorial was created by GitHub user danielb987 so the JMRI repository is danielb987/JMRI.

Depending on the speed of the Internet connection, cloning the JMRI repository to your computer may take a while. It's about two gigabyte of data to download. Be patient!

GitHub Desktop user interface



The GitHub Desktop application has on the top a menu. It can also be accessed by pressing the "Alt" key, which is useful if GitHub Desktop is in full screen mode and the menu is invisible.

Below the menu, there is three "buttons": Current repository, current branch and the Fetch-button. The button "Current branch" is used to select another branch or to create a new branch. Note that branches are cheap, so there is no problem creating new ones as needed.

The last button, "Fetch origin", sends data to and from the GitHub web server. When it says "Fetch origin", it only sync the computer with the server, but once there is commits to either download from the GitHub server to the local computer, or commits to upload from the local computer to the server, this button will tell you about it and once you press the button, the commits will be downloaded or uploaded to the server.

Keeping our branches up to date with JMRI

There are several developers on the JMRI project, adding and changing code all the time. We therefore need to keep our local branches up to date with the JMRI master branch.

First, select the "master" branch to keep it up to date with the JMRI master branch. Then go to the main menu, click on "Branch" and "Merge into current branch".

Then select the upstream/master branch. It's at the bottom of the list.

The text "20 hours ago" tells you when the last change was made to the upstream/master branch. The text "This will merge 14 commits from upstream/master into master" tells you how many commits that are to be merged, from which branch and to which branch. Ensure you have choosen the correct branches!

Click on the button "Merge upstream/master into master" to do the merge. When it's finish, you will see this:

The button "Fetch origin" has now changed its name to "Push origin". The number 14 tells that there is 14 commits to upload to the server.

But wait! Why do we want to _upload_ the commits? Haven't we just downloaded them from JMRI?

Yes, we have downloaded the commits from upstream/master into our local master on the local computer. It's now time to upload these commits to our repository on the GitHub server.

What's happening is this: We are working with three different repositories. For me, my user name on GitHub is danielb987, so I'm working with these three repositories:

What has happen is that we merged "upstream/master" from JMRI/JMRI to our "master" branch in our repository on our local computer. Then we need to upload the changes to our "master" branch on our local computer to our GitHub repository on the GitHub server, which for me is "danielb987/JMRI".

The workflow of JMRI development

The workflow we use:
  1. Select the branch "master"
  2. Ensure "master" is up to date with upstream/master. If it's not, we merge branch "upstream/master" into "master" sa previously described.
  3. Create a new branch. Please use only english letters, digits and underscore for the name of the branch. GitHub Desktop can handle international characters, but if you need help from one of the maintainers, it can be tricky for them to handle the branch if it has international characters. Note that "branches" are cheap. It's no problem to have many of them.
  4. Do a commit then a part of the work is finished. It's often better to have many small commits than one big commit. But it's good if the project at least can compile each commit.
  5. Do the work you need. If it takes a long time, it's highly recommended to merge upstream/master into the branch once a week.
  6. Once the work is done, a "Pull Request" is created. A Pull Request, or PR, is a way to tell the maintainers of JMRI that you have done this work and you want it included into JMRI.
  7. Then a Pull Request, PR, is created, some automatic tools, for example Travis and Code Climate, will start to compile the code and run a big number of tests against it. Most, but not all, of these tools must succeed for the maintainers to be able to merge your work into JMRI.
  8. Once the automatic tools are finished, the maintainers will look at the Pull Request and check it, and if everything seems OK they will merge your work into JMRI.

Creating a new branch to work with

First select the master branch and ensure it's up to date. If it's not, please merge upstream/master into master. Se above.

Click on the button "Current branch" and then click on the button "New branch" and give the new branch a name.



It's not recommended to use international characters or spaces in the branch name. It may cause problems for the maintainers later.

It's possible to create the branch from another branch than the master branch. For example, JMRI may use the branch "development" as the branch to base developent on. If this is the case, you select the development branch, then merge the branch "upstream/development" into the branch "development" and then create the branch from development. Note that if you do this, GitHub desktop will warn you and ask if you really want to start from the development branch or start from the master branch. Select the "development" branch in this case.

When a new branch is created, it only exists on your local computer. In order to push it to the server, we click on the button "Publish branch".

Do a commit

Using your favourite development tool, for example Eclipse or NetBeans, do the changes you want. For the purpose of this text, we create a simple class HelloWord.java.

GitHub Desktop will now show the changes we have done, in this case added a new class. We add a description for the commit that describes what this commit does and then click on the button "Commit to ...". The branch we are commiting to is "hello_world" so the button shows "Commit to hello_world".

We then click the button "Push origin" to upload our commit to the GitHub server. Note that this sends the commit to my repository, not the JMRI repository.

Create a Pull Request, PR

When we have done the commits we want, it's time to do a Pull Request, PR. It tells the maintainers of JMRI that you want this code to be included into JMRI.

In order to do that, we click on the button "Create Pull Request".

This will open a web browser. If you are not logged in to GitHub, you need to log in. When you have logged in, you will see the web page for creation of a Pull Request.

Fill in a title and a description of the Pull Request and click on the button "Create Pull Request".

Sometimes you may want to do some more work on the Pull Request before it's merged, or you may want somebody else to look at it. In these cases, you can mark the Pull Request as "Work In Progress" by writing the letters WIP in the title.

After the Pull Request is created, the following page is shown.

Below "Some checks haven't completed yet" is a list of tools that runs a lot of automatic tests. These tools compile the code, run the tests and checks that everything is correct. If a check is successful, it will have a green check mark, otherwise it will have a red cross.

Not all tests need to be successful for the Pull Request to be merged, only the ones marked with "Required", but it's good if all tests are successful.

After that, you will have to wait for one of the maintainers to take a look at your Pull Request and hopefully merge it into JMRI.

Handling a conflict

There are many programmers working on JMRI simulantiously. This means that it happens that two persons are working at the same piece of code the same time. Most often, Git will be able to handle that, but in some cases conflicts appears that needs to be handled manually.

In our example, we have the method hello():


    public void hello() {
        System.out.print("Hello");
        System.out.println("World");
    }

Lets add a row:

    public void hello() {
        System.out.print("Hello");
	System.out.print(" my ");
        System.out.println("World");
    }


On the right side, you will now see that a new line has been added at row 14. We do a commit and upload it to the server.

Now we want to keep up with upstream/master, so we merge "upstream/master" into "master", and then "master" into our branch "hello_world". We select the branch "master" and merge "upstream/master" into our "master" branch and then select the branch "hello_world" and merge the branch "master" into "hello_world".

(For the case of demonstration, I use the branch hello_world2 to show a conflict).

We now have a problem! Some other guy has made a change in the same code as we, and there is a conflict! GitHub tells that there is one conflicting file between the two branches we want to merge.

In order to solve that, we click on the button "Merge ...".

GitHub now protects us from doing too much damage by requiring us to fix the conflict before we can commit the merge. We have to solve the conflict or abort the merge.

To solve the conflict, we open the conflicting file in our editor, for example NetBeans.

The strange code that is in the file shows there the conflict is, or in some cases there may even be several conflicts in the file.

    public void hello() {
        System.out.print("Hello");
<<<<<<< HEAD
        System.out.print(" my ");
=======
        System.out.print(" your ");
>>>>>>> hello_world2
        System.out.println("World");
    }
There is two parts here. First, beginning with "<<<<<<< HEAD" is the code we want to have. This code goes down to the line "=======". Below that are the code that someone else wants to have, and that code goes down to ">>>>>>> hello_world2". In this case, I have used the branch "hello_world2" to get a conflict, but most often you will have merge master into your branch so this line will be ">>>>>>> master".

What we need to do is to decide if we should keep the original code, replace it with our own, or do something different. The key is to understand what the code does and to make a good decision. If in question, please ask at the JMRI developer mailing list.

In this case, we resolve this by changing the line to:

        System.out.print(" our ");


Then we go back to GitHub Desktop, we see that the conflict is solved and we can now merge the commit.