Basic Github Workflow
Published: 2023-07-25 16:15:07

<em>tldr</em>: We will briefly summarize a basic Github workflow for new computer science students to prevent version conflicts and rebasing. 

As we already know, Github is a powerful version control software that is widely used in the tech industry. Navigating it and its commands in the terminal can be overwhelming, however, as a newcomer to the programming world. In this blog, we will discuss the basics of Github workflow and hope we can make it a little less confusing for new programming students. 

We will assume that the reader has already created a Github account and properly configured their terminal for Github commands. Upon creation of a new repository on Github the user and any collaborators can clone the repository onto their local machine to begin. At this point, all users have a local copy of the master branch on their machines. 

**0**: At this point, all users have the same local master branch on their machines which is a copy of the remote master branch on Github.com. 

All users now run the following command from their terminals while in the directory of the repository:

`git checkout -b <branch-name>` 

The checkout command is used to switch branches. The -b tag signals that we are trying to create a new branch. For your first projects, your branch names will likely simply be your own name. But as your projects grow in complexity it will become useful to name your branches after the features you are implementing. I.e. you are working on the login page of your application so your name your branch `login-01`. Subsequent updates to your login functionality can be made under `login-02`, etc. Similarly, your teammates who may be working on the selection screen might name their branches `selection-01`, etc., etc. 
	
**1**: Now, all users have created a local feature branch in which they will add their code. **!!** No users are coding on their local master branches. 

Let’s say, you’ve finished your changes on the `login-01` branch and would like to push your changes up to the remote master branch. There are a few steps to this. First, your remote Github repository must be given a copy of your local feature branch. To do this, we push your local feature branch to the remote origin by running the following command:

`git push origin <branch-name>`

Now, your origin repository has a copy of your local feature branch. On Github.com we can check that your new branch has been added to repository and create a pull request. Usually on the home page of your repository, Github automatically detects updated branches and provides a quick short-cut button to creating pull requests. All this means is that you are pulling your feature branch changes into the master branch on Github.com. For industry application, usually this is a request because your changes must be approved by your teammates, manager, and sometimes other people too before your changes are added to the master branch. 

For the sake of your first student projects, this won’t be necessary. Once your create your pull request, you’ll be redirected to a page where you can finalize your pull request and merge it into the master branch. As a rule of thumb, it is good to check if the branches can be automatically merged. Github will check this for you and give you a green checkmark if this is the case, if not it will show a red ‘x’. Generally, however, for the first feature branch pull request, there will be no issues and you will be able to pull your feature branch into the master branch. 

In a proper workflow, you can now delete your remote feature branch since the remote master branch contains its changes and so that the remote origin tree can stay clean. 

**2**: Now let’s take stock of the different versions of your project that exist among Github.com and your team’s various machines. 
- Remote Master: contains updated code with your feature branch changes
- Local Master: **does not** contain updated code with your feature branch changes 
- Local Features: 
 - Your teammates have code on their local feature branches not yet merged into the master branch, they are work in progress
 - Your feature branch you **just** merged is now deprecated since its features are integrated into the remote master branch

Next, we have to update all Local Master branches. All team members, including you, can navigate to their local master branches and pulling the changes on the remote master branch by running the following commands:

`git checkout master`
`git pull origin master`

There should be no errors at this point because everybody had the same version of the master branch earlier when we were at (0), before everybody created and started working on their feature branches. 

You can now delete your local feature branch by running the following command:

`git branch -d <branch-name>`

The -d tag indicates that the branch that follows should be deleted. This is no problem because your changes are already integrated into the master branch that is now on your machine as well as your team members’ machines. 

**3**:
- Remote Master: contains all updated code from one feature branch
- Local Master: contains all updated code from one feature branch
- Local Features: 
 - Your teammates local feature branches still do not yet have your feature branch code that you just pulled into the master branch
 - Your local feature branch is now deleted and you and create a new branch to work out of

Your teammates should now pull your changes into their local feature branches from their local master branches they just updated. They can do this by running the following commands:

`git checkout <branch-name>`
`git merge master <branch-name>`

This switches them from their local master branches onto their local feature branches and merges the changes from their local master branches into their local feature branches. If conflicts come up now they can be resolved in the VS code conflict editor or simply within each conflicting file by clicking `accept current`, `accept incoming`, or `accept both` (and manually edit) to resolve any highlighted conflicts in each affected file. This might be overwhelming at first but the key is to simply keep the most updated or correct version of the code. Go one conflict at a time and once all documents are resolved, run the following commands to finish the merge:

`git add .`
`git commit -m “commit message”`

That’s it. 

**4**:
- Local Master: contains all updated code from one feature branch
- Remote Master: contains all updated code from one feature branch
- Local Features: 
 - Your teammates now have the most updated code in general since they have all changes from the master branch in addition to their feature changes which they have not yet merged into the master branch
 - Your new feature branch (login-02, for example) may now also contain new code

Now when it’s your teammate’s turn to add his features, he proceeds from just after (1) above. Once remote master is updated, all team members update their local masters and merge their local masters into their local features before proceeding with their feature branches. Generally speaking, that’s it. 

Maybe that seemed too simple, or maybe it didn’t. Let’s highlight some good practices outlined in the above workflow:

**! -** It’s best not to work on the local master branch; doing this can create conflicts that can only be resolved through rebasing (perhaps a topic for another blog) 

**! -** Pull changes from the remote master before creating your pull request. 

**! -** Commit your changes before checking out into different branches. Or stash your changes if you know your changes might be insignificant (`git stash` simply saves your changes elsewhere you can bring back later if needed)

While this may actually seem too complicated, we follow this workflow in order to minimize conflicts between branches and keep the master branch clean. And when the master branch is clean, our workflow will go smoothly.