Github Practices - hpache/SignLanguageWebsite Wiki

Intro

Github/git are awesome tools that help optimize workflow if they are used correctly. There is a difference between GitHub and Git, Git is the program that tracks any changes within files stored locally. It was created by Linus Torvalds (Linux dude), and the whole purpose was to make collaborative work with other programmers as easy as possible (known as version control). Github is a service that hosts Git repositories, these are known as remote repos stored outside of your local machine. So as a recap, Git is local and Github is remote! Git has a lot of tools and commands that we can use, and Github adds on to those with neat features like Projects, Actions, Issues, and so on... This page aims to help you, a Git/Github starter, learn about these tools and the development workflow expected for this project.

Pull, Add, Commit, and Push

First, we will start with the most basic commands that every Git user should know!

Pull

git pull Is a command from the git CLI, and all it does is pull(download) the most recent code from the remote repository. Before you do anything, you should always pull code from the repo! Again ALWAYS PULL CODE FROM THE REPO BEFORE STARTING ANYTHING. The reason behind this is because we want to prevent any merge/push conflicts; we are working as a group, and there might be a moment in which more than one person is working on the same file. If person A pushes their code to the repo first and the code works, then we won't have a problem. But if we have person B work on that same code and push to the repo, then person B will get a scary error message talking about a conflict. On top of that scary message, person B's code will be modified containing their code and person A's code, and they will be asked to pick which code they want to add or delete. This is a huge pain, and if done multiple times, the GitHub repo can end up being a mess which can only be fixed by deleting the entire thing. This can all be prevented if you always pull code before you start working on anything, it also helps to pull code before pushing your own code just in case someone was working on the same file.

Add

git add is a command that adds the specified files to the staging area. The way Git works is through a four stage process:

  1. You write code on your computer and save it.
  2. You stage the code with git, basically like preparing a package to be shipped.
  3. You move the code from staging to the commit phase, basically like taking a package to the post office and buying the labels/stamps.
  4. You push the code to the remote repo, basically like shipping your package to whoever you are sending it to.

git add puts you in the second stage. Here you can pick which files you want to get ready to be pushed to the repo. It helps to make sure that you are adding the files you want to add, since it is really easy to undo things at this stage.

You can use git add --all to stage all your files, although this is bad practice. I would personally use this for files that were created by another program and have not yet been staged.

Alternatively, you can use git add [file name with extension] to stage individual files. This also gives you the ability to create different commit messages for each file (more on that later).

Commit

git commit is the command that puts you in the third stage. This stage takes all the modified files that are staged, and makes a commit object with them. This object has information on the person who made the changes and the person who committed the changes, along with a unique identifier. Think of this stage as the point of no return; if you modified your code at this point, the changes will not show up, if you added a file by accident, you better undo its commit before moving forward.

git commit will work on its own, but you will end up getting vim along with a message that tells you to write a commit message. In order to avoid that you should always write git commit -m "message here" where your message will be descriptive!

Push

git push is the command that puts you in the final stage. This stage is where your code gets uploaded to the remote repo and everyone gets to see all your work, along with the specific changes that you made. There's really not that much to this command other than the fact that you can't undo a push. Once you do the push, it will be permanent, the only way to go back is through GitHub and a tedious process.

git push on its own works just fine, but I like to do git push origin, that way git knows that it will push to the remote repo, and I can specify which branch I want if needed.

Branching

Branching is a very important concept in Git and it's arguably the thing that makes git extremely useful. Before getting into what branching is, it will help to talk more about Git and how it works to keep track of your files and the modifications you make to it.

Git can be thought of as a bi-directional graph where each commit is a node and each push could be thought of as an edge. You actually have the ability to make a commit, push it, and go back to an earlier commit. If you look closely at the terminal each time you commit something, you can actually spot the key associated with that commit, easier to see on the GitHub app and the website.

If you just use make commits and push them to a repo, then the bi-directional graph looks like a stick without any branches.

------*

This isn't a feature that people noticed after git was made, it was actually designed this way which is why you might sometimes spot words like nodes and branch, in git this stick without any branches is known as the main branch (sometimes called master for some reason). Just working on the main branch is perfectly fine for a small/simple project, and it's fine if you're just using Git/Github to save your projects remotely. The one time this would be bad practice would be when you are working with a group or you are working on a project with multiple parts.

First, if you are working on a project with multiple parts on it, you actually risk significant downtime each time you add a feature and push it to the main branch. Say you have a huge branch, and you have a backlog of five new features. One person can push a new feature to the branch and it can also be extremely buggy because it conflicts with a much earlier feature.

--#-------#

At this point, everyone has to focus on the bug, try to figure out why the bug is happening, and then resolve the bug before any more progress is made. So instead of working on the other features, the team had to resolve one bug; this can get worse when you have multiple bugs.

On the second case would be when you are working on a group and don't have any bugs. In this case, the problem would arise when more than one person is working on the same code at the same time. Here person A would have written code that works and person B would also have code that works. Person A would push to the main branch and everything works fine, but then comes in person B and they get a serious error from Git. This is known as a merge conflict and it describes what happens when Git freaks out that it's updating the same files. When it happens once it's pretty easy to handle (especially if you are using VS code), but when it happens multiple times it can be a pain and can actually lead to one big buggy mess.

The way around these two scenarios is through the use of branching. In the first situation, each new feature will get its new branch, so you will get something like this

  [email protected]@[email protected]
 /

@[email protected]@[email protected] | [email protected]@[email protected]@[email protected]

Notice how in one branch something broke, but in the second branch work on a separate feature is continuing. In this case, bugs are localized to their branch, and the people responsible for that branch are responsible for resolving that bug. Also in this case, new features are added on to the main branch when they have been fully tested, and fully integrated with previous code without any breaking bugs, and if you have a really good team, they are only added to the main branch when the code has been reviewed. This is a common practice within open source projects and software development teams within some cool companies.

In the second scenario a merge conflict is prevented immediately, person A and person B can coordinate to work on the same feature, or person A and person B could make their own branch. In this case, the best code will probably be added to the main branch and someone's feelings are going to get hurt.

How to Make Branches

Making branches is pretty simple in git, instead of just giving you the command, I will give you a checklist, because it is very important that you do this correctly.

So going down the checklist:

  1. git pull origin pulls the code from the main branch on the repo and makes sure you have the most up-to-date code. This is to make sure that your branch has the most recent code at that time, and also adds any new branches to your local git.
  2. git branch -a will list all the branches on your local git and the remote repo. This is mostly for seeing if anyone else is working on the same issue you are working or if you don't want to memorize a branch name.
  3. git checkout main This command moves you to the main branch, remember you are branching off from the main branch so it is good practice to make sure you are on the main branch before you make a new branch.
  4. git branch <name> makes the branch with the name you used. Since you are working from the command line, the branch name cannot have any spaces in it.
  5. git branch -a will be used to make sure the branch was added to your local git repo.
  6. git push -u origin <name> will make sure that your new branch appears on the remote git repo. You can check GitHub to see if this command worked.

Again, all of these steps are here for a reason, so you should follow each step even if it feels redundant, redundancy is never bad when it comes to coding.

Naming Branches

Branch naming has its own scheme and I actually want a specific naming scheme used in this project. Notice how each issue in this project has a label (mostly enhancement). If you read each issue carefully, you can determine what kind of issue it is (new feature, documentation, weird bug). With all that being said, I want the branch names to follow this scheme:

It is very important that you follow this naming scheme, this is a pretty complicated project and I want us to be as organized as possible!

Merging Branches

Merging branches describes the process in which you add code from one branch onto another. Most of the time you do this to the main branch, but there are times in which you have to do this to a different branch. For example, if a new feature was pushed to the main branch, you should update your branch so that new feature is in your branch as well. Branches don't get automatically synced, so it is your responsibility to make sure it is synced! (I might change this later). Regardless, here is the checklist to merge a branch into the main branch

The new commands here are git merge "name" and git branch --merged

  1. git merge "name" merges the branch you specified into the branch you are currently in (in this case the main branch). If you want to merge the main branch to a different branch, all you have to do is checkout to the branch you want to merge to and just run git merge main.
  2. git branch --merged just lists out all the merged branches in your repo. Merging branches does not delete branches at all, so using this command is the best way to check if you merged things correctly.

This checklist is the checklist for a pull request, but there is an easier way to do this.

Pull Requests

Pull requests describes the process in which a branch is being merged to the main branch on the remote repo. You can start this process through the terminal, but it's easier to do it on GitHub. I personally prefer to do this on the website because it's easier to make comments on the pull request, and it's easier to compare code if the branch happens to modify code on the main branch. At the moment, I have a workflow set up so that an html validator runs on each push to the main branch and it will also run during each pull request. If your code fails that validation process, the pull request will be denied until the proper changes are made.

There's nothing else to say about pull requests other than it must be done, your code must be reviewed both by the automated workflow and by someone else, and it must be approved before it goes to the main branch. This isn't to be tough on people, it's to make sure that nothing breaks and we don't waste our time fixing a preventable bug.