Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Discussion 2: Git Skill Practice

Tue Sep 15 (B sections) / Wed Sep 16 (A sections)

Today you and a partner collaborate on a single repo. You will create branches, merge them two different ways, collide with each other on purpose, and come to a resolution.

You have done all the individual pieces already in class: fork, clone, commit, push. This time you'll see what happens when multiple people are trying to do this at the same time.

Work in pairs if you can. If your section has an odd number, talk to your TA to make a plan.

Part 1: One repository, two people

Decide which of you will be "Person A" and which will be "Person B" for the rest of this exercise. Then follow these steps:

  1. A goes to https://github.com/rust4ds/ds210-git-practice and clicks Use this template, then Create a new repository. Name it whatever you like and make it public.

  2. A opens the new repo's Settings, then Collaborators, then Add people, and adds B by their GitHub username.

  3. B accepts the invitation (it arrives by email and/or by notification on github.com depending on your settings).

  4. Both of you clone the repo. It is A's repo, so you both use A's URL:

    git clone <A's repo URL>
    cd <the folder it made>
    cargo run
    

You should both see the same crew with nobody on it.

  1. Both of you run these two lines in your terminal. You'll never have to do these again:

    git config --global pull.rebase false
    git config --global core.editor nano
    

The first tells git pull to combine work by merging, which is what we have taught you. Without it, you'll have issues with git pull.

The second means that when git needs you to write something, you get nano, which you have used, instead of vi, which you have not (and which is much harder to use).

Both of these options will also be helpful for you for Project 1.

Part 2: A branch you merge yourself

In this part, you'll create a new branch, edit it, and try to send your edits up to your shared repo. Whoever does it first will be fine, but whoever gets there second will have to face the fact that your versions have diverged.

Both of you, around the same time, create a new branch by running:

git checkout -b <your-name>-notes

Make a new file called <your-name>.md and write a sentence in it. Then you'll commit your change to your branch, switch back to main, merge your change into main, and push the updated main back up to GitHub:

git add <your-name>.md  # or git add .
git commit -m "Add <your name>'s notes"
git checkout main
git merge <your-name>-notes
git push

The second person who gets there will get an error on that last line. Read it. Git is telling you the other person got there first and you do not have their commit yet. Do what it says:

git pull
git push

Two things to expect from that pull. If it complains about "divergent branches", you skipped step 5 of Part 1: run it and pull again. And when it works, an editor opens with a commit message git has already written for you. You do not have to change it. Save and close, which in nano is Ctrl+X and then Y and the merge finishes.

Check in with each other about what just happened. That pull merged your partner's work into yours and you didn't have to do much to fix the issue. Since you edited different files, git was smart enough to combine the edits without your involvement. Let's make it more interesting...

Part 3: A conflict on your own machine

Same idea, but this time you will edit the same line.

From main (run git status to make sure you're on the main branch still), without telling each other what you are typing, open src/main.rs and change MOTTO to a motto you like. Then:

git add .
git commit -m "Add our motto"
git push

One of you pushes fine. The other is rejected again, so pull like last time:

git pull

This time the pull does not go quietly. Git says CONFLICT (content): Merge conflict in src/main.rs and stops in the middle of the merge. Open the file:

<<<<<<< HEAD
const MOTTO: &str = "Measure twice, push once";
=======
const MOTTO: &str = "Ship it and see";
>>>>>>> 0cf7a8d

Above ======= is what you wrote. Below it is what arrived from GitHub. The letters and numbers at the end is the commit ID ("hash") it came from.

For fun, before you fix the conflict, go ahead and run

cargo run

It won't compile and the compiler says error: encountered diff marker and tells you where. Which is a helpful reminder that we still need to fix this!

You now need to "resolve" the conflict by picking which motto to keep (or creatively combine them), delete all three marker lines, and check your work again with cargo run to make sure it compiles.

Then finish the merge and push:

git add .
git commit -m "Merge mottos"
git push

Remember this moment - something like this is going to come up during Project 1!

Part 4: A branch that goes through a pull request

In Part 2 you merged one branch into another locally by running git merge branch-name from the branch you wanted to merge into. This time we'll see how merging works in GitHub, where you might want to ask your collaborators for feedback or permission before you merge into a critical or even production/operating version of your code.

Both of you:

git checkout main
git pull
git checkout -b <your-name>-crew

Make these two edits, and only these:

  • In src/main.rs, change CREW_NAME to a crew/team name you like.

  • In src/main.rs, replace the (nobody has signed on yet) line with one for yourself like:

    #![allow(unused)]
    fn main() {
    println!("  - Your Name");
    }
  • In README.md, fill in the crew name under ## Crew name and put yourself under ## Members.

Then commit and push the branch itself to github:

git add .
git commit -m "Name the crew and sign on"
git push -u origin <your-name>-crew

git push -u origin branch-name sets up the link between your local branch and GitHub, and is only needed the first time you push after creating the branch. If you update your branch further all you'll need to do in the future to track it is run git push.

Now both of you go to GitHub, and you should both see a banner offering to open a pull request. (If you don't see the banner, you can create a Pull Request by going to the Pull Requests tab, then "New Pull Request" and setting "base" to main and "compare" to your own branch.)

In the right-hand sidebar, under Reviewers, request your partner by their GitHub name (since they're a collaborator, it should pop up quickly). Then submit your pull request.

Now review each other. Open your partner's pull request (you should have gotten an email as a reviewer, and can also find it in the pull requests tab), click Files changed, then Review changes. Leave a comment on a line, choose Approve, and submit.

Then merge only ONE of them. Decide together which pull request goes first and merge it with Merge pull request.

Part 5: The second pull request

Go and look at the one you did not merge, and refresh the page. GitHub now says "This branch has conflicts that must be resolved." You both changed the same lines, and git will refuse to pick a winner.

Whoever submitted the pull request that's still open now needs to fix it. Go back to your machine, and first merge in the other person's edits:

git checkout main
git pull
git checkout <your-name>-crew
git merge main

Note you had to go back to main and pull from there. git pull only updates the branch you are standing on.

Now, git will stop and list the files it could not merge. Open src/main.rs. You will again find markers like this:

<<<<<<< HEAD
const CREW_NAME: &str = "Team Segfault";
=======
const CREW_NAME: &str = "The Borrow Checkers";
>>>>>>> main

Above ======= is your version. Below it is what is already on main. Like before, you need to decide what the file should say in the end, and delete all the markers. There are two of these in src/main.rs and one in README.md.

When you're done, check with cargo run. When it prints both of you under one crew name, you can finish:

git add .
git commit -m "Resolve conflicts: keep both names, one crew"
git push

Refresh the pull request, and you'll see the conflict banner is gone. Now the other person can approve and merge it.

Part 6: Look at what you built

Both of you can try this now:

git checkout main
git pull
git log --graph --oneline

Find the merges and pull requests in the tree.

Talk about it with your partner:

  • Both routes put a branch onto main. What does the pull request give you that git merge on your own machine does not?
  • Nobody reviewed the Part 2 merge. When would that be fine, and when would it not be?
  • Realistically, how could you think about organizing your collaborations to prevent conflicts like the ones that arose today before they happen?

Submitting

Both partners submit, separately, on Gradescope (the assignment called Discussion 2 Activity). You will need to write:

  • The URL of the repository you worked in. Both of you submit the same one.
  • The output of git log --graph --oneline from main.
  • One or two sentences: what your conflict was, and how you decided to resolve it.

More git practice

None of these are required, but can provide some additional opportunities to practice (though the best way to practice is just to do it for real!)

Browser, nothing to install

  • Learn Git Branching is a visual sandbox for branching, merging, rebasing, and remotes. Start with the Introduction sequence, then Remote. It draws the commit graph as you type which helps you picture what's going on.
  • Git Mastery is a level-based game covering staging, branches, stash, reset, and rebase. May feel a little fast at first and its ability to simulate real merging and collaboration is limited.

Desktop apps

  • Oh My Git! teaches basic git as a card game, with the commit graph drawn live. Good if the command line is still the part slowing you down (and it gives extra gold stars if you go back and do it at the command line after).
  • Git-It walks you through the basics against your real GitHub account. Worth doing for challenges 1 through 7. Stop after "Branches Aren't Just For Birds." Challenges 8 and 10 check your work against a server that has been down recently so that part cannot be completed.

Reading

  • Pro Git is the free official book. Chapter 3 is branching, and it has an especially clear explanation of merging.
  • GitHub Docs for pull requests, reviews, and everything from Part 3.
  • Git Immersion is a guided command-line walkthrough. The examples are in Ruby but the git is the same.