In class. Nothing to hand in.
In this lab, you'll learn about
git branches,
merging, and branch deletion.
These concepts should put you on the road to making git a powerful collaboration tool
rather than a mysterious source of confusion and pain.
A little advice
Take your time with this lab. There's no hurry. Go slow, and take a look around after every operation.
Keep your eyes open for changes and confusing bits. Keep a list of questions and ask more than
one person for their answers. You're after an understanding of how git works, and that
takes time, experimentation, and a fair amount of puzzlement before understanding arrives.
Resources
Here are a few tutorials and references that I have found useful as I have learned
about branching, etc.
One handy command: viewing your commit graph
When I'm working on a project that branches frequently (typically because I'm working with
at least two or three other people), I find it very helpful to be able to see the "commit graph"—that
is, a diagram of the commits, branches, merges, etc. One way to get a pretty clean picture of
the commit graph is:
git log --all --graph --decorate --oneline
This generates a display that looks like this:
You can create an alias for this command and put it in the .gitconfig file in your home
directory (works in any Unix environment, including Windows bash):
[alias]
graph = log --all --graph --decorate --oneline
which lets you do just "git graph" to get the cool diagram.
Setup: two clones of the repository
You're going to have two separate clones of your repository, and we'll call the people
manipulating those two clones Alice and Bob. It might be that Alice is using one computer
and Bob is using a different computer, or it might be that you're all alone and have
two separate terminal windows open, so you're playing the role of both Alice and Bob.
Here's how to get started.
- Alice and Bob: decide on which repository to use. I recommend just choosing
one of your "assignments-whoever" repositories that you're using for homework
for this class.
- Alice: git clone URL_TO_YOUR_REPO
- Bob: git clone URL_TO_YOUR_REPO
- If you created an empty repo for this lab, Alice should
add a file (maybe readme.md?), then commit and push it, and Bob should then
do "git pull". Collaborating on an empty repo can generate some slightly
weird warnings that go away once there's been at least one commit.
- Alice and Bob: "git pull" should result in "Already up-to-date."
- Alice and Bob: "git push" should result in "Everything up-to-date."
- Alice and Bob: "git log" and should show the same thing for Alice and
Bob. (So should the fancy "git log" described above.)
- Alice and Bob: "git branch -a -v" should show the same list of branches for Alice and Bob.
Experiment 1: Merging without branches
- First, Alice. Bob, just wait for Alice to do these things.
- Create a directory called "git-experiments" at the top level of your repository.
- Create a file called "cat.txt" inside git-experiments, containing whatever you want
(my "cat.txt" just contains "Meow").
- git add git-experiments/cat.txt
- git commit -m "added cat.txt"
- git pull (should be up-to-date already)
- git push
- Bob
- Do not "git pull" yet. That would eliminate the value of the experiment.
- Create a directory called "git-experiments" at the top level of your repository.
- Create a file called "dog.txt" inside git-experiments, containing whatever you want
(my "dog.txt" just contains "Woof").
- git add git-experiments/dog.txt
- git commit -m "added dog.txt"
- Everybody pause and look at Bob's computer. Bob, do the fancy "git log..."
described above so you can see your commit graph.
- git pull. This should toss you into your editor (vi, or whatever)
with a pre-written commit message, like "Merge branch 'master' of...". Just save and
quit from the editor.
- Everybody pause and look at Bob's computer. Bob, do the fancy "git log..."
again. How does your graph look now? Does it make sense?
- What files are in git-experiments?
- git push
- Alice's turn again
- git pull
- Anything weird? Did you have to save and quit from an editor or anything?
- Do the fancy "git log". Does it look like Bob's?
- Everybody
- Talk to each other
- Study the commit graph
- What happened? Does it make sense? What does "merge" mean in this context?
Experiment 1.5: git checkout
Alice, with everybody watching and discussing
- Do the fancy git log. Where is "HEAD"?
- Do a simple git log.
Identify the commit from just before cat.txt and dog.txt were added. It has
a "commit hash" (a long hexadecimal number). Let's call it COMMIT_HASH.
- git checkout COMMIT_HASH.
- Take a look at the contents of Alice's repository. Are cat.txt and dog.txt
there? Is git-experiments?
- Do the fancy git log. Where is "HEAD" now?
- Can you move HEAD to the commit where dog.txt was created? Is dog.txt there?
Is cat.txt there? Why or why not?
- git checkout master
- Where is HEAD now? What do the files look like?
- What does "git checkout" do?
Experiment 2: Merging without branches, but with a merge conflict
Don't forget: make sure Alice's and Bob's clones are both in the same state before moving on.
- Alice: Change the first line of cat.txt to "Alice likes cats"
- Alice: commit, pull (should be up-to-date already), push
- Bob: Change the first line of cat.txt to "Bob likes cats"
- Bob: commit, pull
- Bob: holy cow, what just happened? Open up cat.txt. You should see a line with a bunch
of <<<<<<'s, a line with a bunch of ======'s, and a line with
a bunch of >>>>>>>'s. What's in between them?
- Bob: "resolve the conflict" by removing the special lines from cat.txt
and editing the file into its desired form (often but not always this will simply
involve picking either Alice's or Bob's changes and discarding the other changes).
- Bob: commit, pull (should be up-to-date already), push
- Alice: pull
- Everybody: how do things look in the two clones now?
Experiment 3: Branching
- Everybody: git branch -a. Any idea what those "remotes/origin" things are about?
- Everybody: git branch -v. What does the "-v" do? What does the "*" mean?
- Everybody: git branch -a -v. Describe the functions of "-a" and "-v".
- Alice
- Create the new branch: git branch goat
- Take a look at the commit graph. Where's HEAD? See anything new?
- Take a look at the list of branches (git branch -a -v). See anything new?
- Switch to using the new branch: git checkout goat
- Take a look at the commit graph and the list of branches. Where's HEAD?
- Create a file git-experiments/goat.txt, put whatever you want in it.
- Add, commit
- Push the new branch to github: git push -u origin goat
(note that you only have to do the "-u origin goat" stuff once; normal pushing works
fine after that)
- Take a look at the commit graph and the list of branches. Where's HEAD? See anything new?
- Bob
- Take a look at the commit graph and the list of branches. Where's HEAD?
- pull
- Take a look at the commit graph and the list of branches. See anything new? Where's HEAD?
- Take a look at the contents of git-experiments. See any goats?
- Create a file git-experiments/moose.txt, put whatever you want in it.
- Add, commit, pull (should be up-to-date already), push
- Take a look at the commit graph. Where's HEAD? See anything new?
- git checkout goat
- Take a look at the commit graph. Where's HEAD?
- Take a look at the contents of git-experiments. See any goats? See any moose?
- Alice
- pull
- Take a look at the commit graph and the list of branches.
- Do you see moose.txt? What would you need to do to see moose.txt? Is it
possible to see moose.txt and goat.txt at the same time?
- Everybody: talk about what happened, what confuses you, etc. and write down some questions.
Later, you could share your questions on the Slack #questions channel.
Experiment 4: Merging a branch
- Alice and Bob: git pull
- Alice and Bob: git checkout master
- Alice and Bob: take a good look at the commit graph and the list of branches. Understand
what's happened today? Questions?
- Alice merges the goat branch into master: git merge goat
- Alice: Look at the commit graph. What's new?
- Alice: Look at the files. See any goats or moose?
- Alice: git push
- Bob: git pull
- Bob: look at the commit graph and branch list. What's new?
Experiment 5: Deleting a branch
This is pretty involved. You have to make sure that both Alice and Bob agree that
the goat branch needs to be deleted, and it has to be explicitly deleted in
Bob's clone, Alice's clone, and the remote repository (GitHub, in this case).
There's a great Stack Overflow post about git branch deletion that's worth reading. The steps listed below
come in part from this post.
- Bob deletes the goat branch: git branch -d goat
- Bob tells GitHub to delete it, too: git push origin --delete goat
- Alice: git pull --all --prune. The "--prune" makes sure
git deletes the goat branch from Alice's clone of the repository.
- Alice and Bob: look at the commit graph and branch list. Are the goat-branch commits still
there? Is the label "goat" visible anywhere? Is the goat.txt file present in the master branch?
- So what got deleted, and what's left over?
A simple github workflow and pull requests
Coming soon in a separate lab...