Examples of common collaboration workflows that vary by team and by project, and how to use repository hosts like GitHub and Bitbucket or host Git repositories on private servers like GitLab.
Now that we’ve covered some of the tools needed to use Git effectively on solo projects, it’s time to learn about what is perhaps Git’s greatest strength: making it easier to collaborate with other people. This is especially the case when using repository hosts like GitHub (https://github.com/) or Bitbucket (https://bitbucket.org/), but it is also possible to host Git repositories on private servers (sometimes using software like GitLab (https://about.gitlab.com/) to get many GitHub-like benefits).
Because this tutorial is designed for individual readers, we won’t actually be able to collaborate with others, but this chapter will explain how you can practice “collaborating” with yourself. There are many different collaboration scenarios, and they vary significantly by team and by project, so we’ll focus on the important case of multiple collaborators who all have commit rights to a particular repo. This model is appropriate for teams where everyone can make changes without explicit approval from a project maintainer.
Open-source projects typically use a different flow involving forking and pull requests, but the details differ enough that it’s best to defer to the collaboration instructions of each particular project. Consider, for example, the instructions for contributing to Ruby on Rails (https://guides.rubyonrails.org/contributing_to_ruby_on_rails.html). With the commands from this tutorial and your technical sophistication (Box 8.2), you’ll be in a good position to understand and follow such instructions if you decide to get involved in contributing to open-source software or other projects under version control with Git.
For reference, important commands from this chapter are summarized in Section 11.5.
11.1 Clone, Push, Pull
As an example of a common collaboration workflow, we’ll simulate the case of two developers working on the same project, in this case the simple website developed in this tutorial. We’ll start with Alice (Figure 11.1)1 working in the original website directory, and we’ll create a second directory (website-copy) for her collaborator Bob (Figure 11.2).2
Figure 11.1: Alice, working on website.
Figure 11.2: Bob (with son Tim), working on website-copy.
As a first step, Alice runs git push just to make sure all her changes are on the remote repository:
[website (main)]$ git push
In real life, Alice would now need to add Bob as a collaborator on the website repository, which she could do at GitHub by clicking on Settings > Manage Access > Invite a collaborator and then put Bob’s GitHub username in the invitation box (Figure 11.3). Because we’re collaborating with ourselves, we can skip this step.
Figure 11.3: The GitHub page to add collaborators.
Once Bob gets the notification that he’s been added to the website repository, he can go to GitHub to get the clone URL, as shown in Figure 11.4. This URL lets Bob make a full copy of the repository (including its history) using git clone.
Figure 11.4: Finding the clone URL at GitHub.
Ordinarily, Bob would probably use his own repos directory, with a project called website as in Alice’s original, but because we’re only simulating the collaboration we’ll use the name website-copy for clarity. In addition, when doing something a little artificial like this, I like to use a temp directory called ~/tmp,3 so create this directory if it doesn’t already exist on your system:
$ cd $ mkdir tmp
Then cd to it and clone the repo to the local directory:
[~]$ cd tmp/ [tmp]$ git clone <clone URL> website-copy Cloning into 'website-copy'... [tmp]$ cd website-copy/
Here we’ve included the argument website-copy to git clone, thereby showing how to use a different name than the original repo, but usually you just run git clone <clone URL>, which uses the default repo name (in this case, website).
Now we’re ready to open the copy of the project and start making edits:
[website-copy (main)]$ atom .
For the purposes of this exercise, I recommend placing the editor windows for website and website-copy side by side, as shown in Figure 11.5.
Figure 11.5: The website and website-copy editors running side by side.
To begin the collaboration, we’ll have Bob make a change to the site by wrapping the tutorial title on the About page in a link, like this:
<a href="https://www.learnenough.com/git-tutorial">…</a>
Here the ellipsis … represents the full title of the tutorial, Learn Enough Git to Be Dangerous. The resulting line is too long to display here, but we can wrap it, as shown in Figure 11.6, with the result as shown in Figure 11.7.
Figure 11.6: Toggling soft wrap in Atom.
Figure 11.7: The About page with soft wrap activated.
If we look at the diffusing git diff, we see the wrapped line (Figure 11.8), which appears in a browser as shown in Figure 11.9.
Figure 11.8: The diff with a wrapped line.
Figure 11.9: Linking the Git tutorial title on the About page.
Having added the link, Bob can commit his changes and push up to the remote repository:
[website-copy (main)]$ git commit -am "Add link to tutorial title" [website-copy (main)]$ git push
At this point, Bob might send Alice a notification that there’s a change ready, or Alice might just be diligent about checking for changes. In either case, Alice can get the changes from the remote origin by running git pull. I suggest opening up a new tab in your terminal window for Alice’s directory (as shown in Figure 11.10) and then pull as follows:
Figure 11.10: Using a new terminal tab for the original directory.
[website (main)]$ git pull remote: Enumerating objects: 5, done. remote: Counting objects: 100% (5/5), done. remote: Compressing objects: 100% (1/1), done. remote: Total 3 (delta 2), reused 3 (delta 2), pack-reused 0 Unpacking objects: 100% (3/3), 336 bytes | 168.00 KiB/s, done.
From https://github.com/mhartl/website cad4761..9a9cecf main -> origin/main Updating cad4761..9a9cecf Fast-forward about.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
With that, Alice’s project should have Bob’s commit, and her copy of the About page should be identical to Figure 11.9. (Checking that Bob’s commit is present in the log is left as an exercise.)
11.1.1 Exercises
As Alice, run git log to verify that the commit was pulled down correctly. Double-check the details using git log -p.
The whale picture added in Listing 10.1 (Figure 10.1) requires attribution under the Creative Commons Attribution-NoDerivs 2.0 Generic license. As Alice, link the image to the original attribution page, as shown in Listing 11.1. Commit the result and push to GitHub.
As Bob, pull in the changes from the previous exercise. Verify by refreshing the browser and by running git log -p that Bob’s repo has been properly updated.