Tutorial

IntelliJ with GitHub

Programming as a team introduces special challenges. You’ll need extra communication to keep everyone productive, and additional tools to keep from losing work.

Professional environments use Revision Control Systems to store the code, communicate the changes, and keep people from overwriting each other’s work.  FRC programming teams should also use Revision Control.

Probably the most popular revision control system right now is git, a distributed version control system created by Linus Torvalds, the same guy who created Linux. You can use git from the command line, or from within development environments such as Eclipse, IntelliJ, and Visual Studio Code.  GitHub is a web-based hosting service for git, and the GitHub corporation is a FIRST sponsor.  All programming mentors and students can get free GitHub accounts, and FIRST teams can get upgraded Team Accounts.

To say that git is “distributed” means that every programmer will have a copy of the code, along with the history of the changes.  There is also one remote repository of the code out on the internet. Programmers will occasionally pull changes from the remote repository to their local copy and occasionally push their own changes up to the remote repository.  In this way, everyone eventually has the same code and the same history.

Combinations of the code files are called “commits“, and the word “commit” here is both a noun and a verb.  Committing your changes creates a commit that you can retrieve later.

OK, I know that that was a lot of information.  Honestly, git is a really deep subject, and companies that use it develop really complicated methodologies for its use.  I do not recommend that FRC teams try to use everything in the git toolkit, or try to emulate commercial practices.  Especially at first.  Instead, let’s lay out the minimal functions.

Installing and configuring git

IntelliJ provides an excellent user interface to git, much better than the UI in Eclipse or VS Code.  However, the git package is separate from IntelliJ.  You must install it on your laptop.  Instructions are at:  https://git-scm.com/ .

You should configure git to know who you are.  This information will be added to the repository very time you commit.  Open up a terminal window and execute the following:

git config --global user.email "myEmailAddress@whereever.com"
git config --global user.name "My real name"

Cloning an existing repository

Suppose that there is a repository on GitHub that you’d like to download to your laptop.  Making a local copy is called making a clone.

Consider the code repository at:  https://github.com/firebears-frc/testrobot0.  Go ahead and visit that page in a browser.  Press the green button labeled “Clone or Download” and then press the little clipboard button.  This will copy the repository’s formal URL into your clipboard.

vsc_git_clone

Now go to IntelliJ:

  1. From the main menu select File > New > Project from version control > git
  2. Paste your git URL into the “Clone Repository” dialog.  Click “OK” and open the new project in the current window.
  3. A dialog may appear asking if you want to import a Gradle project.  You do.
    If the dialog gets lost, open your project in the Project tool window.  Right-click on the build.gradle file and select “Import Gradle Project”.

At this point you now have a clone of the repository on your machine.  You won’t be able to push changes up to the remote repository unless the owner has granted you permission, but you can read, edit, and deploy this code to the robot.

Creating a new repository

Suppose you have a robot project on your local machine that has never been under git control, but you’d like to upload it into GitHub.   Open your project in IntelliJ and then:

  1. From the menu select VSC > Import into Version Control > Share Project on GitHub.
  2. Log on with your GitHub account:
    intellij_github_login.png
  3. Specify the repository name and description:
    intellij_github_share
  4. Make the initial commit of all your files:
    intellij_github_commit_1
  5. Now go to your browser and visit the page on https://github.com for your new repository.  You should now see all the files listed on the web page.

Note that this process has initialized your local project to be tracked by git.    You’ll notice that there is now a “Version Control” tab at the bottom of the window that will open the Version Control tool window.  The “Local Changes” tab will show files that have been added or modified since your last commit.

intellij_github_vc.png

Also notice the branch indicator in the lower right corner of the screen.  This will be used when you start managing multiple branches in your repository.

Committing changes to the code

From now on, when you add files, delete files, or modify files, git and IntelliJ will keep track of how your code differs from the most recent commit.  The Local Changes tab keeps track of what has changed.  When you are ready to make a commitment, select the files, right-click, and select “Commit”.

intellij_github_commit_2

Type in a commit message.  Try to write informative messages, since you and others will be reading this later.  Good messages say things like “Updated autonomous commands for new encoder” or “Code changes after first regional”.   Bad messages contain jokes or gibberish or say things like “changed stuff”.

intellij_github_commit_3

After entering a useful message, hit the “Commit” button.  This will commit your changes locally, but will not yet push those changes upstream to Github.

Pulling changes back from the repository

Suppose someone else has made changes to the code and pushed them up to the remote repository.  You’d like to fetch those changes and merge them into our code.  This is called doing a pull from the remote.

You can pull at any time, but it is usually best to commit your code locally before pulling.  That is to say, commit the code but don’t push it up yet.  Follow the directions in the previous section to do the commit.

To pull down changes, select from the main menu:  VCS > Git > Pull.   The best case scenario (which is usually what happens) is that upstream changes will be seamlessly added to your code and everything will work perfectly.

One thing that might go wrong is that the changes pulled in will invalidate or undo something you are doing.  You should always look over the incoming changes.

The worst case scenario is that someone else will have changed files that you are working on, and you will need to “merge” changes.  The Conflicts dialog will show which files are in conflict:

intellij_github_merge_1

For each conflicting file, you will have three options

  • Accept Yours : ignore all changes in the remote repository and stick with your changes.
  • Accept Theirs : overwrite this file with the file from the remote repository.
  • Merge: Manually decide how the conflict will be resolved.  This involves picking out individual changes will be copied from your branch or from the remote branch.  If neither change looks right, you can edit text in the middle panel any way you like:intellij_github_merge_2.png

After you’ve modified a conflicted file and saved the changes, go back to the Local Changes view.   After merging all the conflicts, perform another “Commit”.

Pushing your changes up to the repository

If you are ready to release your changes to the rest of the group, you can push your commits up to the remote repository.  Use the menu options VCS > Git > Push.

Synching with the remote repository

There’s an important discipline that everyone must develop with respect to the remote repository, which is that you should always pull in remote changes before pushing up your own.  If there are incoming changes, then you must recheck the merged code to verify that it is OK.

With multiple programmers, you should perform the following steps manually:

  1. Commit your changes locally.
  2. Pull remote changes, and deal with any merge conflicts.
  3. Verify that the merged code compiles correctly and that the code works correctly.  If there are any problems, fix them and then go back to step 1.
  4. Push all commits to the remote repository.

Further Reading:

Leave a comment