Skip to main content

Section 4.6 GitHub - Git in the Cloud

The most popular SECPs include GitHub 1 , Gitea 2 , GitLab 3 , and Bitbucket 4 . All of these use Git for version control and all provide cloud storage space for Git repositories. Of these, GitHub is the single largest host for Git repositories and is the central point of collaboration for millions of developers and projects. A large percentage of all Git repositories are hosted on GitHub, and many open-source projects use it for Git hosting, issue tracking, code review, and other things. So while it’s not a direct part of the Git open source project, there’s a good chance that you’ll want or need to interact with GitHub at some point while using Git professionally. Other hosting services work similarly.
Watch the following video from GitHub to learn more.
Figure 4.6.1. What is GitHub?
Obviously, the first thing you need to do is set up a free user account. If you do not already have one, simply visit https://github.com 5  and follow the directions.

Subsection 4.6.1 Contributing to a Project

Next, let’s walk through some details that could be useful in helping you contribute to an existing open source project.

Forking Projects.

If you want to contribute to an existing project to which you don’t have write access (aka push access), you can fork the project. When you “fork” a project, GitHub will make a copy of the project that is entirely yours; it lives in your namespace, and you can push to it.
In GitHub, a “fork” is simply a copy of the project in your own namespace, allowing you to make changes to a project publicly as a way to contribute in an open manner. Note: Historically, the term “fork” has sometimes had a negative connotation if it meant that someone took an open source project in a different direction, creating a competing project and splitting the contributors.
This way, projects don’t have to worry about adding users as collaborators to give them push access. People can fork a project, push to it, and contribute their changes back to the original repository by creating a merge request which in GitHub is called a pull request. We’ll cover this next. Making a pull request opens up a discussion thread with code review, and the owner and the contributor can then communicate about the change until the owner is happy with it, at which point the owner can merge it in.
To fork a project, visit the project page and click the “Fork” button at the top-right of the page. This gives you a copy of the project in the GitHub cloud.
Once you have your own fork on GitHub, you need to clone a local copy down to a place where you can edit it, most typically your own local computer. Note that while you can make small changes in GitHub, it is not a good practice to do so.
Let’s try this!
Checkpoint 4.6.2. Exercise – Fork a Repo.
Go to GitHub: Fork a Repo 6  and complete the provided exercise with the octocat/Spoon-Knife repository.

The GitHub Flow.

GitHub is designed around a particular collaboration workflow, centered on pull requests and idea of a branches as covered in Section 4.4.. This flow works whether you’re collaborating with a tightly-knit team in a single shared repository, or a globally-distributed company or network of strangers contributing to a project through dozens of forks.
After you read the project’s README contributor’s page and get a sense of the community norms, here’s how the Git workflow generally works:
  1. Fork the project.
  2. Create your own topic branch from main (or master or another branch name, depending upon the project).
  3. Make some commits to improve the project, being sure to follow community expectations, such as linking the issue that you are fixing.
  4. Push this branch to your GitHub fork.
  5. Open a Pull Request on GitHub.
  6. Discuss, and optionally continue committing.
  7. Hopefully, the project owner eventually merges or closes the Pull Request.
  8. Sync the updated main (or master) back to your fork.
Let’s walk through an example of proposing a change to an open source project hosted on GitHub using this flow.
Checkpoint 4.6.3. Exercise – GitHub Flow.
Go to GitHub Flow 7  and complete the provided exercise with one of your own repositories.
Creating a Pull Request.
You can always go to the “Branches” page at https://github.com/<user>/<project>/branches to locate your branch and open a new Pull Request from there.
You can also see a list of the commits in our topic branch that are “ahead” of the main or master branch (in this case, just the one) and a unified diff of all the changes that will be made should this branch get merged by the project owner.
When you hit the ’Create pull request’ button on this screen, the owner of the project you forked will get a notification that someone is suggesting a change and will link to a page that has all of this information on it.
Note: Though Pull Requests are used commonly for public projects when the contributor has a complete change ready to be made, it’s also often used in internal projects at the beginning of the development cycle. Since you can keep pushing to the topic branch even after the Pull Request is opened, it’s often opened early and used as a way to iterate on work as a team within a context, rather than opened at the very end of the process.
Let’s give this a try!
Iterating on a Pull Request.
At this point, the project owner can look at the suggested change and merge it, reject it or comment on it. Let’s say that he likes the idea, but would prefer a slightly longer time for the light to be off than on.
Where this conversation may take place varies by community, on GitHub this typically happens online. The project owner can review the unified diff and leave a comment by clicking on any of the lines.
Once the maintainer makes a comment, the person who opened the Pull Request (and indeed, anyone else watching the repository) will get a notification.
Note that anyone can also leave general comments on the Pull Request.
Now the contributor can see what they need to do in order to get their change accepted. Luckily this is very straightforward. With GitHub you simply commit to the same topic branch again and push, which will automatically update the Pull Request.
Adding commits to an existing Pull Request doesn’t trigger a notification, so once you push corrections you might want to to leave a comment to inform the project owner that you made the requested change.
An interesting thing to notice is that if you click on the “Files Changed” tab on any Pull Request, you’ll get a “unified” diff — that is, the total aggregate difference that would be introduced the main branch if this topic branch was merged in. In git diff terms, it basically automatically shows you git diff main<branch> for the branch this Pull Request is based on.
GitHub always checks to see if the Pull Request merges cleanly and provides a button to do the merge for you on the server. This button only shows up if you have write access to the repository and a trivial merge is possible. If you click it GitHub will perform a “non-fast-forward” merge, meaning that even if the merge could be a fast-forward, it will still create a merge commit.
If you prefer, you can simply pull the branch down and merge it locally. If you merge this branch into the main branch and push it to GitHub, the Pull Request will automatically be closed.
This is the basic workflow that most GitHub projects use. Topic branches are created, Pull Requests are opened on them, a discussion ensues, possibly more work is done on the branch and eventually the request is either closed or merged.
Note: It’s important to note that you can also open a Pull Request between two branches in the same repository. If you’re working on a feature with someone and you both have write access to the project, you can push a topic branch to the repository and open a Pull Request on it to the main branch of that same project to initiate the code review and discussion process. No forking necessary.

Advanced Pull Requests.

Now that we’ve covered the basics of contributing to a project on GitHub, let’s cover a few interesting tips and tricks about Pull Requests so you can be more effective in using them.
Pull Requests as Patches.
It’s important to understand that many projects don’t really think of Pull Requests as queues of perfect patches that should apply cleanly in order, as most mailing list-based projects think of patch series contributions. Most GitHub projects think about Pull Request branches as iterative conversations around a proposed change, culminating in a unified diff that is applied by merging.
This is an important distinction, because generally the change is suggested before the code is thought to be perfect. This depends wholely on the community. In communities where it is used, it enables an earlier conversation with the maintainers so that arriving at the proper solution is more of a community effort. When code is proposed with a Pull Request and the maintainers or community suggest a change, the patch series is generally not re-rolled, but instead the difference is pushed as a new commit to the branch, moving the conversation forward with the context of the previous work intact.
This way if you go back and look at this Pull Request in the future, you can easily find all of the context of why decisions were made. Pushing the “Merge” button on the site purposefully creates a merge commit that references the Pull Request so that it’s easy to go back and research the original conversation if necessary.
Keeping up with Upstream.
If your Pull Request becomes out of date or otherwise doesn’t merge cleanly, you will want to fix it so the maintainer can easily merge it. GitHub will test this for you and let you know at the bottom of every Pull Request if the merge is trivial or not.
If your Pull Request does not merge cleanly you’ll want to fix your branch so that it turns green.
You have two main options in order to do this. You can either rebase your branch on top of whatever the target branch is (normally the main branch of the repository you forked), or you can merge the target branch into your branch.
Most developers on GitHub will choose to do the latter, for the same reasons we just went over in the previous section. What matters is the history and the final merge, so rebasing isn’t getting you much other than a slightly cleaner history and in return is far more difficult and error prone.
If you want to merge in the target branch to make your Pull Request mergeable, you would add the original repository as a new remote, fetch from it, merge the main branch of that repository into your topic branch, fix any issues and finally push it back up to the same branch you opened the Pull Request on.
  1. Add the original repository as a remote named upstream.
  2. Fetch the newest work from that remote.
  3. Merge the main branch of that repository into your topic branch.
  4. Fix the conflict that occurred.
  5. Push back up to the same topic branch.
Once you do that, the Pull Request will be automatically updated and re-checked to see if it merges cleanly.
One of the great things about Git is that you can do that continuously. If you have a very long-running project, you can easily merge from the target branch over and over again and only have to deal with conflicts that have arisen since the last time that you merged, making the process very manageable.
If you absolutely wish to rebase the branch to clean it up, you can certainly do so, but it is highly encouraged to not force push over the branch that the Pull Request is already opened on. If other people have pulled it down and done more work on it, you will run into major problems! Instead, push the rebased branch to a new branch on GitHub and open a brand new Pull Request referencing the old one, then close the original.
References.
Your next question may be “How do I reference the old Pull Request?”. It turns out there are many, many ways to reference other things almost anywhere you can write in GitHub.
Let’s start with how to cross-reference another Pull Request or an Issue. All Pull Requests and Issues are assigned numbers and they are unique within the project. For example, you can’t have Pull Request #3 and Issue #3. If you want to reference any Pull Request or Issue from any other one, you can simply put #<num> in any comment or description. You can also be more specific if the Issue or Pull request lives somewhere else; write username#<num> if you’re referring to an Issue or Pull Request in a fork of the repository you’re in, or username/repo#<num> to reference something in another repository.
In addition to issue numbers, you can also reference a specific commit by SHA-1. You have to specify a full 40 character SHA-1, but if GitHub sees that in a comment, it will link directly to the commit. Again, you can reference commits in forks or other repositories in the same way you did with issues.

GitHub Flavored Markdown.

Linking to other Issues is just the beginning of interesting things you can do with almost any text box on GitHub. In Issue and Pull Request descriptions, comments, code comments and more, you can use what is called “GitHub Flavored Markdown”. Markdown is like writing in plain text but which is rendered richly.
The GitHub flavor of Markdown adds more things you can do beyond the basic Markdown syntax. These can all be really useful when creating useful Pull Request or Issue comments or descriptions.
Task Lists.
A useful GitHub specific Markdown feature, especially for use in Pull Requests, is the Task List 9 . A task list is a list of checkboxes of things you want to get done. Putting them into an Issue or Pull Request normally indicates things that you want to get done before you consider the item complete.
These are often used in Pull Requests to indicate what all you would like to get done on the branch before the Pull Request will be ready to merge. The really cool part is that you can simply click the checkboxes to update the comment — you don’t have to edit the Markdown directly to check tasks off.
What’s more, GitHub will look for task lists in your Issues and Pull Requests and show them as metadata on the pages that list them out. For example, if you have a Pull Request with tasks and you look at the overview page of all Pull Requests, you can see how far done it is. This helps people break down Pull Requests into subtasks and helps other people track the progress of the branch.
These are incredibly useful when you open a Pull Request early and use it to track your progress through the implementation of the feature.
Code Snippets.
You can also add code snippets to comments. This is especially useful if you want to present something that you could try to do before actually implementing it as a commit on your branch. This is also often used to add example code of what is not working or what this Pull Request could implement.
To add a snippet of code you have to “fence” it in backticks.
```java
for(int i=0 ; i < 5 ; i++)
{
   System.out.println("i is : " + i);
}
```
If you add a language name like we did there with ’java’, GitHub will also try to syntax highlight the snippet.
Quoting.
If you’re responding to a small part of a long comment, you can selectively quote out of the other comment by preceding the lines with the > character. In fact, this is so common and so useful that there is a keyboard shortcut for it. If you highlight text in a comment that you want to directly reply to and hit the r key, it will quote that text in the comment box for you.
The quotes look something like this:
> Whether 'tis Nobler in the mind to suffer
> The Slings and Arrows of outrageous Fortune,

How big are these slings and in particular, these arrows?

Keep your GitHub public repository up-to-date.

Once you’ve forked a GitHub repository, your repository (your "fork") exists independently from the original. In particular, when the original repository has new commits, GitHub informs you by a message like:
This branch is 5 commits behind progit:main.
But your GitHub repository will never be automatically updated by GitHub; this is something that you must do yourself. Fortunately, this is very easy to do.

Subsection 4.6.2 Maintaining a Project

Now that we’re comfortable contributing to a project, let’s look at the other side: creating, maintaining and administering your own project.

Creating a New Repository.

Let’s create a new repository to share our project code with. Start by clicking the “New repository” button on the right-hand side of the dashboard, or from the + button in the top toolbar next to your username.
All you really have to do here is provide a project name; the rest of the fields are completely optional. For now, just click the “Create Repository” button, and boom – you have a new repository on GitHub, named <user>/<project_name>.
Since you have no code there yet, GitHub will show you instructions for how to create a brand-new Git repository, or connect an existing Git project.
Now that your project is hosted on GitHub, you can give the URL to anyone you want to share your project with. Every project on GitHub is accessible over HTTPS as https://github.com/<user>/<project_name>, and over SSH as git@github.com:<user>/<project_name>. Git can fetch from and push to both of these URLs, but they are access-controlled based on the credentials of the user connecting to them.
Note: It is often preferable to share the HTTPS based URL for a public project, since the user does not have to have a GitHub account to access it for cloning. Users will have to have an account and an uploaded SSH key to access your project if you give them the SSH URL. The HTTPS one is also exactly the same URL they would paste into a browser to view the project there.

Adding Collaborators.

If you’re working with other people who you want to give commit access to, you need to add them as “collaborators”. If Ben, Jeff, and Louise all sign up for accounts on GitHub, and you want to give them push access to your repository, you can add them to your project. Doing so will give them “push” access, which means they have both read and write access to the project and Git repository.
Click the “Settings” link at the bottom of the right-hand sidebar.
Then select “Collaborators” from the menu on the left-hand side. Then, just type a username into the box, and click “Add collaborator.” You can repeat this as many times as you like to grant access to everyone you like. If you need to revoke access, just click the “X” on the right-hand side of their row.

Managing Pull Requests.

Now that you have a project with some code in it and maybe even a few collaborators who also have push access, let’s go over what to do when you get a Pull Request yourself.
Pull Requests can either come from a branch in a fork of your repository or they can come from another branch in the same repository. The only difference is that the ones in a fork are often from people where you can’t push to their branch and they can’t push to yours, whereas with internal Pull Requests generally both parties can access the branch.
Email Notifications.
Someone comes along and makes a change to your code and sends you a Pull Request. You should get an email notifying you about the new Pull Request.
There are a few things to notice about this email. It will give you a small diffstat — a list of files that have changed in the Pull Request and by how much. It gives you a link to the Pull Request on GitHub. It also gives you a few URLs that you can use from the command line.
Collaborating on the Pull Request.
As we covered above, you can now have a conversation with the person who opened the Pull Request. You can comment on specific lines of code, comment on whole commits or comment on the entire Pull Request itself, using GitHub Flavored Markdown everywhere.
Every time someone else comments on the Pull Request you will continue to get email notifications so you know there is activity happening. They will each have a link to the Pull Request where the activity is happening and you can also directly respond to the email to comment on the Pull Request thread.
Once the code is in a place you like and want to merge it in, you can either pull the code down and merge it locally, either with the git pull <url> <branch> syntax we saw earlier, or by adding the fork as a remote and fetching and merging.
If the merge is trivial, you can also just hit the “Merge” button on the GitHub site. This will do a “non-fast-forward” merge, creating a merge commit even if a fast-forward merge was possible. This means that no matter what, every time you hit the merge button, a merge commit is created.
If you decide you don’t want to merge it, you can also just close the Pull Request and the person who opened it will be notified.
Pull Requests on Pull Requests.
Not only can you open Pull Requests that target the main or main branch, you can actually open a Pull Request targeting any branch in the network. In fact, you can even target another Pull Request.
If you see a Pull Request that is moving in the right direction and you have an idea for a change that depends on it or you’re not sure is a good idea, or you just don’t have push access to the target branch, you can open a Pull Request directly to it.
When you go to open a Pull Request, there is a box at the top of the page that specifies which branch you’re requesting to pull to and which you’re requesting to pull from. If you hit the “Edit” button at the right of that box you can change not only the branches but also which fork.

Mentions and Notifications.

GitHub also has a pretty nice notifications system built in that can come in handy when you have questions or need feedback from specific individuals or teams.
In any comment you can start typing a @ character and it will begin to autocomplete with the names and usernames of people who are collaborators or contributors in the project.
You can also mention a user who is not in that dropdown, but often the autocompleter can make it faster.
Once you post a comment with a user mention, that user will be notified. This means that this can be a really effective way of pulling people into conversations rather than making them poll. Very often in Pull Requests on GitHub people will pull in other people on their teams or in their company to review an Issue or Pull Request.
If someone gets mentioned on a Pull Request or Issue, they will be “subscribed” to it and will continue getting notifications any time some activity occurs on it. You will also be subscribed to something if you opened it, if you’re watching the repository or if you comment on something. If you no longer wish to receive notifications, there is an “Unsubscribe” button on the page you can click to stop receiving updates on it.
The Notifications Page.
When we mention “notifications” here with respect to GitHub, we mean a specific way that GitHub tries to get in touch with you when events happen and there are a few different ways you can configure them. If you go to the “Notification center” tab from the settings page, you can see some of the options you have.
The two choices are to get notifications over “Email” and over “Web” and you can choose either, neither or both for when you actively participate in things and for activity on repositories you are watching.
Web Notifications.
Web notifications only exist on GitHub and you can only check them on GitHub. If you have this option selected in your preferences and a notification is triggered for you, you will see a small blue dot over your notifications icon at the top of your screen.
If you click on that, you will see a list of all the items you have been notified about, grouped by project. You can filter to the notifications of a specific project by clicking on its name in the left hand sidebar. You can also acknowledge the notification by clicking the checkmark icon next to any notification, or acknowledge all of the notifications in a project by clicking the checkmark at the top of the group. There is also a mute button next to each checkmark that you can click to not receive any further notifications on that item.
All of these tools are very useful for handling large numbers of notifications. Many GitHub power users will simply turn off email notifications entirely and manage all of their notifications through this screen.
Email Notifications.
Email notifications are the other way you can handle notifications through GitHub. If you have this turned on you will get emails for each notification. The emails will also be threaded properly, which is nice if you’re using a threading email client.
There is also a fair amount of metadata embedded in the headers of the emails that GitHub sends you, which can be really helpful for setting up custom filters and rules.
There are a couple of interesting things here. If you want to highlight or re-route emails to this particular project or even Pull Request, the information in Message-ID gives you all the data in <user>/<project>/<type>/<id> format. If this were an issue, for example, the <type> field would have been “issues” rather than “pull”.
The List-Post and List-Unsubscribe fields mean that if you have a mail client that understands those, you can easily post to the list or “Unsubscribe” from the thread. That would be essentially the same as clicking the “mute” button on the web version of the notification or “Unsubscribe” on the Issue or Pull Request page itself.
It’s also worth noting that if you have both email and web notifications enabled and you read the email version of the notification, the web version will be marked as read as well if you have images allowed in your mail client.

Special Files.

There are a number of special files that GitHub will notice if they are present in your repository. We detail a few of the most common ones. Note that these can typically be written in any format that GitHub recognizes as prose.

LICENSE.

The first is the LICENSE file, which can be of nearly any prose format. For example, it could be LICENSE, LICENSE.md, LICENSE.asciidoc, etc.
The license file explains the respostory’s legal license, including any legal rights, any copyright restrictions, etc. When you include a detectable license in your repository, people who visit your repository will see it at the top of the repository page.
For more information on how to add a license, see Adding a license to a repository 10 

README.

The README file explains your project, what it does, why it is useful, etc. If GitHub detects a README file in your source, it will render it on the landing page of the project, so this file is often the first item a visitor will see when visiting your repository.
Many teams use this file to hold all the relevant project information for someone who might be new to the repository or project. This generally includes things like:
  • What the project is for
  • How to configure and install it
  • An example of how to use it or get it running
  • The license that the project is offered under
  • How to contribute to it
Since GitHub will render this file, you can embed images or links in it for added ease of understanding.

CODE_OF_CONDUCT.

The CODE_OF_CONDUCT file explains how one is expected to engage in that particular community. It is typically used to ensure an inclusive environment that respects all people and also typically describes how to address any problems among members of the project’s community.

CONTRIBUTING.

Another special file that GitHub recognizes is the CONTRIBUTING file. If you have a file named CONTRIBUTING with any file extension, GitHub will show it when anyone starts opening a Pull Request.
The idea here is that you can specify specific things you want or don’t want in a Pull Request sent to your project. This way people may actually read the guidelines before opening the Pull Request.

Project Administration.

Generally there are not a lot of administrative things you can do with a single project, but there are a couple of items that might be of interest.
Changing the Default Branch.
If you are using a branch other than “main” or “master” as your default branch that you want people to open Pull Requests on or see by default, you can change that in your repository’s settings page under the “Options” tab.
Simply change the default branch in the dropdown and that will be the default for all major operations from then on, including which branch is checked out by default when someone clones the repository.

Section Summary.

Now you’re a GitHub user. You know how to create an account, manage an organization, create and push to repositories, contribute to other people’s projects and accept contributions from others.

Checkpoint 4.6.5.

Arrange some of the steps below to contribute an edit to an existing project using established GitHub workflow:
You have attempted of activities on this page.