Start tracking your progress
Trailhead Home
Trailhead Home

Work with the GitHub Workflow

Learning Objectives

After completing this unit, you’ll be able to:

  • List the steps in the GitHub workflow.
  • Explain the difference between the remote and local working environments.
  • Complete the steps to create a new file and make changes to an existing file.

Flow chart showing code, then collaborate, and then ship.

Overview of the GitHub Workflow

The GitHub flow is a lightweight workflow that lets you experiment with new ideas safely, without fear of compromising a project. The main steps are:

  1. Create a branch off of master
  2. Make commits
  3. Open a pull request
  4. Collaborate
    1. Make more commits
    2. Interact with integrations
  5. Merge to master branch

Create a Branch
Branching is a key concept within Git. Everything in Git lives on a branch. By default, the production version of your project lives in the master branch. 

When you’re ready to experiment with a new feature or fix an issue, create a new branch of the project. The branch will look exactly like master at first, but any changes you make will only be reflected in your branch. 

Make Commits
As you make changes to the files within the project, commit them to your feature branch.

Open a Pull Request and Collaborate
Open a pull request to start discussing your changes. A pull request is meant to be a starting point for further code refinement—no need for it to be a perfect work of art.

Merge to Master Branch
Once your team approves your changes, merge your pull request from the feature branch into the master branch. 

So that’s great in theory, but let’s put this into practice.

Install Git

Before we can work through the Git examples in the rest of this unit, the first thing you'll do is install Git on your computer. This sets you up to work with repositories locally. Visit the Git website and follow instructions to install the official version of Git. Accept all the default settings during installation.

Sign Up for a GitHub Account and Create a Repository

The first thing you’ll do is sign up for a GitHub personal account. This is a free version of GitHub and will allow you to follow along with the steps below.

Next create a repository to work with.

  1. In the header, click  Plus icon image and select New repository
  2. Enter a Repository name: best-repo-ever
  3. Choose whether the project is public or private. (We recommend public for now; public repositories are free.)
  4. Select to Initialize this repository with a README
  5. Click Create repository

Screenshot of the repository creation screen.

Working on GitHub Versus Working Locally

You can make changes to your project directly on GitHub, but most people prefer to work on their local machine so they can make changes in their favorite IDE or text editor. Let’s review a couple important terms:

  • The remote repository is the copy of the repository on GitHub. All collaborators synchronize their changes with this, making it the source of truth for the group.
  • Local repositories are git repositories stored on a user's computer. If the local directory is linked to a remote repository, then the local repository is a full copy with everything on the remote repository, including all of its files, branches, and history.

The local and remote repositories only interact when you run one of the four network commands in Git: git clone, git fetch, git pull, and git push.

To work locally on a repository, you first need to create a clone on your machine. To clone a repository, follow these steps:

  1. In GitHub, click the Code tab of the repository you just created
  2. Click Clone or download
  3. Copy the clone URL to your clipboard
  4. Open your command line application. If you are on a Mac or Linux, you can use your terminal. If you are on Windows, we recommend you use Git Bash, which comes installed with Git.
  5. Retrieve a full copy of the repository from GitHub: git clone <CLONE-URL>. Replace <CLONE-URL> with the clone URL you copied above. You should see something like this:
    Cloning into 'best-repo-ever'... 
    remote: Counting objects: 3, done. 
    remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 
    Unpacking objects: 100% (3/3), done.
  6. Once the clone is complete, cd into the new directory created by the clone operation: cd best-repo-ever

Note: You can also use a desktop application like GitHub Desktop to interact with Git and GitHub. These offer a more visual interaction with the repository and are often very powerful.

Configure Your Local Environment

Before you can make changes to your code, you need to set a few basic configurations. You typically only need to set these configurations once. Git lets you set configuration options at three different levels.

git config --system
These are system-wide configurations. They apply to all users on this computer.
git config --global
These are the user-level configurations. They only apply to your user account.
git config--local
These are the repository-level configurations. They only apply to the specific repository where they are set. The default value for git config is --local.

Git adds several configurations automatically—type git config --list to see config settings from all three levels.

Git uses the config settings for your user name and email address to generate a unique fingerprint for each of the commits you create. You can't create commits without these settings, so set them yourself using your command line application:

$ git config --global user.name "First Last" 
$ git config --global user.email "you@email.com"

Note: You won't see any confirmation that this worked, but as long as you don't see an error, you're set!

Configure autocrlf
Next, we set core.autocrlf (autocrlf stands for auto carriage return line feed). Different systems handle line endings and line breaks differently. If you open a file created on another operating system and do not have this config option set, Git will think you made changes to the file based on the way your operating system handles the line endings.

For Windows users enter:

$ git config --global core.autocrlf true

For Mac or Linux users enter:

$ git config --global core.autocrlf input

Track a File with GitHub

Now that you have a local copy of the repository and you have configured Git, you’re ready to use the GitHub Workflow to make some changes to the project. Let’s start by making a simple change to the README.md file. 

Step 1: Create a Branch

To see a list of local branches, type git branch. Right now, you probably only see one branch: master

Let’s create a new branch (myfeaturebranch) for our work:

  1. Type git branch myfeaturebranch
  2. Checkout to that branch: git checkout myfeaturebranch

You should see something like this:

kjameson-ltm:best-repo-ever kjameson$ git branch 
   * master  
kjameson-ltm:best-repo-ever kjameson$ git branch myfeaturebranch 
kjameson-ltm:best-repo-ever kjameson$ git checkout myfeaturebranch 
  Switched to branch 'myfeaturebranch'

Note: If you’ve heard of checkout from other VCS, it likely means something different than in Git. With Git, checkout moves an important pointer called HEAD, and in this case, moves us to a different branch. HEAD points to the tip of your branch. We talk more about HEAD in our last unit. 

Step 2: Make Changes to README.md File and Commit the Change to Your Local Repository

Now that you’ve checked out to the new branch, well make some changes and see Git in action.

  1. Open the README.md in your repository
  2. Add some content using your favorite text editor.
  3. When you’re finished, save your changes.

After you made some changes to your file, it’s time to create your first snapshot. When working from the command line, you will need to be familiar with the idea of the two stage commit.

When you work locally, your files exist in one of four states. They are either untracked, modified, staged, or committed. Git tracks these files, and keeps track of your history by organizing your files and changes in three trees. They are working, staging (also called index), and history. When we add, delete, and make changes to files, we do this in the working tree.

Diagram of the three trees of Git, working, staging, and history.

To add your changes to version control, create a collection of files that represent a discrete unit of work—we build this unit in the staging area.

When we are satisfied with the unit of work we’ve assembled, we take a snapshot of everything in the staging area. This is called a commit.

Let’s complete the process using the commands git add and git commit

  1. Check the status of our working tree: git status
    kjameson-ltm:best-repo-ever kjameson$ git status 
    On branch myfeaturebranch 
    Changes not staged for commit: 
          (use "git add <file>..." to update what will be committed) 
          (use "git checkout -- <file>..." to discard changes in working directory)  
       modified: README.md 
    no changes added to commit (use "git add" and/or "git commit -a")
  2. Move the file from the working tree to the staging area: git add README.md
  3. Enter git status to see what happened:
    kjameson-ltm:best-repo-ever kjameson$ git status
    On branch myfeaturebranch 
    Changes to be committed: 
          (use "git reset HEAD <file>..." to unstage)
       modified: README.md 
  4. Take our first snapshot: git commit -m “My first commit”
  5. Let’s take another look at our repository status: git status
    kjameson-ltm:best-repo-ever kjameson$ git status
    On branch myfeaturebranch 
    nothing to commit, working tree clean

Step 3: Send Changes to the Remote Repository

Right now, this commit is only local. If you check the remote repository, you won’t see your branch or the changes you just made. To see the changes on the remote, you first need to push your changes to the remote repository. 

Since we created this branch locally, we’ll first create a remote branch that matches our local one. With the same command, we’ll also set up a tracking relationship between the two branches.

  1. Type git push -u origin myfeaturebranch
  2. When asked, enter your GitHub username and then your password.
    kjameson-ltm:best-repo-ever kjameson$ git push -u origin myfeaturebranch 
    Username for 'https://github.com': kierenjameson 
    Password for 'https://kierenjameson@github.com': 
    Counting objects: 6, done. 
    Delta compression using up to 4 threads. 
    Compressing objects: 100% (4/4), done. 
    Writing objects: 100% (6/6), 551 bytes | 0 bytes/s, done. 
    Total 6 (delta 1), reused 0 (delta 0) 
    remote: Resolving deltas: 100% (1/1), done. 
    To https://github.com/kierenjameson/best-repo-ever.git
       * [new branch] myfeaturebranch -> myfeaturebranch 
    Branch myfeaturebranch set up to track remote branch myfeaturebranch from origin.

Note:  You only need this long command the first time you push a new branch. After that, you can simply type git push.

Step 4: Create a Pull Request

Now that you’ve pushed your changes to your remote repository, let’s open a pull request on GitHub. 

  1. Go to your GitHub account on the web
  2. Click the Pull Request tab
  3. Click New Pull Request
  4. In the Base dropdown, choose master
  5. In the Compare dropdown, choose myfeaturebranch. You should see something like this:

Screenshot from GitHub showing comparison of changes between master branch and myfeaturebranch.

  1. Click Create pull request
  2. Enter a Subject line and Comment
  3. Click Create pull request

Control Code Quality with Code Review

Pull requests are more than just a comparison of branches, they’re a way to review code and ensure quality, through both human and automated efforts.

General Conversation
Use the Conversation tab to add general comments on a pull request.

Line Comments
In the Files Changed tab (A), can hover over a line to see a blue + icon (B). Clicking this icon will allow you to enter a comment (C) on a specific line. These line level comments are a great way to give additional context on recommended changes. They will also be displayed in the conversation view.

Screenshot showing how to add line comments.

Review
When you are making line comments, you can also choose to Start a Review (D). When you create a review, you can group many line comments together with a summary message. When you submit the review, you can indicate whether it is just a comment, an approval, or a request for changes. Pull request reviews have special power in GitHub when used in conjunction with protected branches, you can prevent a pull request from being merged if it has not had at least one review.

Automated Tests
If you’ve integrated CI/CD with your project, you will see the status of your tests reported right on the pull request. These tests are highly customizable.

Merge Your Changes

When you merge your branch, you take the content and history from your feature branch and add it to the content and history of the master branch.

Merging is quick and easy—click Merge pull request, add a merge comment, and click Confirm merge.

Your team should establish rules about who should merge a pull request. Some options include:

  • The person who created the pull request should merge, as they’ll need to resolve issues resulting from the merge.
  • Assign a single person within the project team. This ensures consistency but can become a bottleneck.
  • Anyone other than the person who created the pull request can merge. This ensures at least one review has taken place.

Keeping It All in Sync

After you merge your pull request, delete the branch on GitHub. To do this click Delete branch at the bottom of the pull request screen.

However, merging and deleting on GitHub will not automatically update your local copy of the repository. Let’s go back to our command line application and get everything in sync.

First, we need to get the changes we made on GitHub into our local copy of the repository:

  1. Switch back to your default branch: git checkout master
  2. Retrieve all of the changes from GitHub: git pull
    kjameson-ltm:best-repo-ever kjameson$ git checkout master 
    Switched to branch 'master' 
    Your branch is up-to-date with 'origin/master'. 
    
    kjameson-ltm:best-repo-ever kjameson$ git pull 
    remote: Counting objects: 1, done. 
    remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0 
    Unpacking objects: 100% (1/1), done. 
    From https://github.com/kierenjameson/best-repo-ever 
           f464053..599f35f master -> origin/master 
    Updating f464053..599f35f 
    Fast-forward 
       README.md | 4 +++- 1 
       file changed, 3 insertions(+), 1 deletion(-)

Note:  git pull is a combination command that retrieves all of the changes from GitHub and then updates the branch you’re currently on, to include the changes from the remote. The two separate commands being run are git fetch and git merge.

retargeting