Welcome back, this article is part 2 of Erik’s Code Space’s series on professional version control with Git. In part one, we learned about the basics of making commits, branching, and merging. In this section, we’re going to learn about the collaboration tools available to us with Git through GitHub. Let’s get started!
In this part of the Git series, we’re going to learn about the tools that exist to help us collaborate with other developers. We’re going to learn about three general concepts: publishing, cloning , and making pull requests.
- Publishing is when we put our own projects out into the world to be viewed, downloaded, and tweaked by anyone. This is what people mean when they tell you to have your own side projects up for potential employers to see.
- Cloning is when you copy someone else’s project onto your own computer so that you can work on or use it. In Git, “cloning” is almost synonymous with “downloading.” Instead of downloading binaries of a program though, we get the actual source code.
- Pull Requests (sometimes called Merge Requests) are what you create when you’ve made changes to a project and you want to merge it into the main project. Recall that in part one we learned that merging meant adding events to the true history of a project. When you collaborate with other developers, your changes typically need to be reviewed before they’re merged into a project.
If you haven’t already, you should head over to GitHub and sign up; don’t worry, it’s free. Signing up should be pretty straightforward basic stuff. You don’t have to worry about stuff like your About Me, profile picture, and other stuff if you don’t want to. Just finish setting up and get to your homepage.
Once you’ve set up your profile, we need to get your local Git configuration aligned with your profile information. Open up your command line of choice so we can start on this. The commands you should run are the following:
$> git config --global user.name "username" $> git config --global user.email "firstname.lastname@example.org
The next thing we need to do is get SSH enabled. Personally, I hate this step and any time I have to redo this step, I have to go and relearn to do it. The official docs for doing this are really great if you want a much more precise guide to it than I’m about to give you, they can be found here.
If you’ve decided to stick with me, the first thing we have to do is generate an SSH key. If you’re on Linux, you should already have the ability to do this from the terminal with
ssh-keygen. If you’re on Windows, the best way to do this is with Git Bash, which should have come with your installation of Git. If not, go back to the download page and download it again. You can find Git Bash by typing bash into your search box and clicking this icon:
From the Bash terminal, run
ssh-keygen -t rsa -b 4096 -C "email@example.com". The resulting prompt will ask you what path and filename to save the key into, put something like “~/.ssh/gittutorial” or something you’ll be able to remember. The next question will ask you to make a passphrase; this is optional and is just for providing a bit of extra security. You can just press enter to go with no passphrase.
Now we need to add our key to the ssh-agent. To be honest with you, I don’t really understand the point of this step, but I know it’s necessary, so let’s power through it together. First, you need to make sure the ssh-agent is running. It probably is but just in case, run the following command:
$> eval `ssh-agent -s`
Note that the characters around
ssh-agent are backticks (Shift + ~). If after running this command you see something like “Agent pid 5278”, you’re good to go. If not, please refer to this article on the GitHub docs.
Once we know the agent is running, we simply add our newly generated key with
ssh-add ~/.ssh/gittutorial. You will be prompted again for your passphrase, just retype it or press enter if you didn’t make one.
Now we need to add your public SSH key to the GitHub profile. On GitHub, click your profile thumbnail in the top right of the screen and click “settings.” From here, go to “SSH and GPG keys” in the left menu. Click “New SSH key” at the top. In the next screen, give your SSH key a title. I typically name the keys after whatever computer that key is for.
Now, head back to your terminal and run
cat ~/.ssh/gittutorial.pub and copy the output (if you have a program called clip installed, you can run
clip < ~/.ssh/gittutorial.pub). Back in your browser, paste the contents into the “key” field. Check carefully for an errant line break, if your key ends with your email, but your cursor is on the next line, hit backspace to get rid of that character.
Click “Add SSH Key” when you’re done and that should be the end of that. Everything we just did is so that we can clone and push repositories remotely. Getting this out of the way will save us some time for the rest of this article.
Now that our profile is ready to go, it’s time to make a new repository. As a reminder, a “repository” is another name for a project’s source code. In part one, we likened it to a company with our commits being the company’s timeline. The “repository” is where all our code will live. From now on, I will call the repository the “repo.”
From the GitHub homepage, in the left menu, you should see a button that says “New” with a book icon. Click it! The next screen will ask you to name the repo, I’m going to go with “ecs-git-tutorial.”
The next selection is the choice to make the repo public or private. I typically keep my repositories private until they’re ready to be used or viewed, but I will keep this one public and I invite you to do the same. Finally, click the option about generating a README and then click “Create repository.”
The next screen will be pretty boring, it’s the home page and README of your mostly empty repository. You’ve officially created a repository on GitHub. It may be a small step but congratulations anyway!
As I mentioned earlier, cloning a repository means to copy it’s contents into your local computer. This is a fairly straightforward process, so let’s jump right into it.
On your repo’s main page, there should be a green button that says “Code” with a down arrow. Click it and select the SSH option. Copy the address in the input bar by clicking the clipboard icon on the right of the Clone pop up.
Go back to your command prompt and type
git clone firstname.lastname@example.org:user/project replacing the part after “clone” with the thing you just copied. For example, for me to clone the repository I just created, I would run:
$> git clone email@example.com:erik-whiting/ecs-git-tutorial.git
Yours will be slightly different. After you hit enter, you’ll see a few outputs and finally you’ll get your prompt back. Run
ls to see the contents and notice that there’s now a folder called
ecs-git-tutorial. Go ahead and
cd into it and run
ls again. Notice that the README is in there. That’s the same README you see on your repository’s homepage on GitHub. We’ve successfully cloned the repo onto our local machine!
Now that you know how to do this, you know how to clone just about any project that’s maintained on GitHub. For example, one of the most popular repos for GitHub is rich, a project that gives you “rich text and beautiful formatting in the terminal.” If you wanted to look through the code of that project on your own IDE, you know how to do that now: with
Most of the time you clone a project from GitHub, it’s so that you can make your own contributions and push them. Let’s do that right now to get a feel for it. Make a new file called “tutorial.txt” and put something simple in there like:
Hi, I'm a text file
Add the file to the repository with
git add tutorial.txt and make a simple commit, something like
git commit -m "First commit". Now we’ve got this tutorial.txt file and commit history on our local computer only. We now want to publish our changes by pushing them. To push your changes to the repo, run the following command:
$> git push
Once again, you’ll see a few outputs in the terminal. If everything went according to plan, we just successfully pushed the tutorial.txt file to GitHub. Go back to your browser and refresh your repo’s homepage. You should now see a new file called “tutorial.txt” with “First commit” and how long ago you committed the file. mine looks like this:
Pretty cool right? We’ve gotten the changes we made on our local machine up to GitHub where anyone can see them. This means anyone with access to GitHub can now clone our work and collaborate with us!
Typically, pushing changes directly to the main branch is considered very bad practice. We generally use a workflow involving “pull requests,” which we’ll learn about next.
Most of the time when we collaborate on projects with multiple developers, or even when we’re working on our own projects, we don’t want to do work on the main branch. Instead, we follow a workflow that involves creating a new branch locally, doing our work, publishing the branch in the repository, and creating a pull request for it. Let’s go through this workflow together.
From your terminal, create a new branch called “edit-tutorial.txt.” If you forgot how to do that, the following command will create and checkout the branch:
$> git checkout -b edit-tutorial.txt
Now, open up the tutorial.txt file and add another line to it, something like “This line was added from the edit-tutorial.txt branch.” From your terminal, run
git status to make sure you see that tutorial.txt has been modified. Go ahead and commit these changes with:
$> git commit -am "Add line to tutorial.txt"
After committing, run
git push. Notice that we get an error that says
fatal: The current branch edit-tutorial.txt has no upstream branch. To push the current branch and set the remote as upstream, use
git push –set-upstream origin edit-tutorial.txt
What happened here? Well, we tried to publish our changes to a branch that doesn’t exist upstream, or in our repo on GitHub. Right now, the only branch on GitHub should be
main. We have to create the branch on GitHub in order to publish our local branch. Doing so is as easy as running the command suggested by the error message though, so simply run:
$> git push --set-upstream origin edit-tutorial.txt
The terminal will again output some information. Once it’s done, go back to the repo’s homepage. You should see a message about a branch having new pushes with a button to “Compare & pull request” like this:
Just in case you don’t see that though, you can click “Pull Requests” in the menu, and click “New pull request” in the next screen. In the next screen, you’d have to change the “compare” dropdown to “edit-tutorial.txt” and click “Create pull request” to create the pull request or PR.
In the next screen, you’re given the option to title and write a comment about the PR. The default title is the last commit message, but I typically like to name them something more official sounding. I also like to add a little description to the PR, but it’s not required. Here’s what my PR looks like:
Now, before finishing the creation of the PR, scroll down on this page and notice that you can now see the incoming changes. I prefer “Split” view to “Unified” (those options are in the top right of the screen relative to the file comparison section of the screen). On the left you’ll see the code that exists in the
main branch, on the right you’ll see the changes made highlighted in green (deletions would be highlighted in red). This is usually a good time to look over the changes you’ve made to make sure you didn’t miss anything important.
Go ahead and click the “Create pull request” button to finish creating the PR. You’ll then be taken to the homepage of the PR
Typically, the repository owner will be doing this next step. From the pull request’s page, the reviewer can look at the changes made in your branch. They can leave comments, tag your username with the @ symbol to notify you, and even comment directly on lines of code.
Let’s pretend we’re the reviewers of this PR. We look through the proposed changes and we decide everything is good to go. The next step is to click the “Merge pull request” button, which should be enabled because there should not be any conflicts with the base branch. If there were conflicts, the button would be disabled.
After clicking the “Merge pull request” button, it’ll change to “Confirm merge.” Click it again to confirm and note the new message “Pull request successfully merged and closed.” We can click the “Revert” button if we need to undo this merge, but since everything is fine, let’s go ahead and delete the branch.
**Note: Some teams prefer to delete branches once they’ve been merged, others don’t. Make sure to always adhere to the repository’s norms.
Go back to your repo’s homepage (by clicking “ecs-git-tutorial” in the top right) and click the
tutorial.txt file. You should now see the line “This line was added from the edit-tutorial.txt branch” we just added. We’ve successfully merged our changes!
Back in your terminal, checkout the main branch again by running:
$> git checkout main
You’ll get a message that says:
Switched to branch 'main' Your branch is up to date with 'origin/main'
but that’s not true. After checking out main, open tutorial.txt in a text editor. What do you notice? You’ll see that the line we added in the PR isn’t in our local copy of
main. What gives?
Well, we actually just need to sync our local
main branch with the remote
main branch on GitHub. First, we can sync our data by running
git fetch which will update our local repository with notifications of any changes made to remote (NOTE! The
fetch command does not update your local branches, it only updates your repository with current information about the repo like PRs made or if your branches are behind).
git status and you should now see a message about being behind by a few commits. Mine looks like this after running the
$> git status On branch main Your branch is behind by 'origin/main' by 2 commits, and can be fast-forwarded. (use "git pull" to update your local branch) nothing to commit, working tree clean
To pull the changes from the merged PR onto our local
main branch, we simply have to run
git pull. Run that in your terminal and open the tutorial.txt file again. You should notice this time that the “This line was added from the edit-tutorial.txt branch” line is in there now.
And that concludes our lesson on merging pull requests!
This concludes part two of our professional git series. We now know how to initialize a repository, make and commit changes, make new branches, publish on GitHub, and create pull requests. That’s a ton of useful information and if your next job is anything like mine, this is stuff you will do multiple times a day, so it’s good you know how to do it now.
Also, this is all the information you need to know in order to participate in open source software (OSS) on GitHub. You now have all the tools you need to start contributing to public projects (if you want to, that is)!
In the next and final part of this series, we will learn rebasing and bisecting, two git commands that are not so common, but are super useful when you need them. Until next time, let me know if you have any questions by emailing me at firstname.lastname@example.org, or tweet at me @ErikWhiting4 (I just got a new Twitter, give me a follow!)