We've talked about using git push
to send local changes to GitHub, but when using git to collaborate with others it's likely that you'll end up in the opposite situation, where there are changes on GitHub you don't have locally. Git provides the git pull
command to handle this.
To demonstrate git pull
, we've provided a repository to work with. Follow these instructions to get started:
- Find a partner
- One partner should fork the repository linked in the calendar
- Whoever forked the repo should add the other partner as a collaborator.
- Both partners should clone the forked repo.
- Both partners should open
pull_practice.rb
in VS Code or Rubymine.
Look at Task 1
in the pull_practice.rb
.
- Partner 1 should uncomment the
duck_noise
method and save the file. - Partner 1 should then
git add
the file,git commit
, andgit push
. You should now be able to see the changes on GitHub. - Partner 2 should run
git pull
. This will retrieve all commits from GitHub that aren't yet on the local repository. - You should now be able to see the
duck_noise
method uncommented in partner 2's copy of the repo.
Switch roles and do the same thing for Task 2
, the truck_noise
method.
Running git pull
when you don't have any changes is also known as performing a fast-forward merge.
What happens if both partners have made changes? Turns out git is pretty intelligent about putting together work from different sources. Most of the time, even if you're working in the same file, it can figure out the right thing to do.
Turn your attention to Task 3
in the activity. Here are your instructions:
-
Partner 1 should uncomment the
robot_noise
method and save the file. -
Partner 1 should then
git add
the file,git commit
, andgit push
. You should now be able to see the changes on GitHub. -
Without pulling, Partner 2 should now uncomment the
train_noise
method and save the file. -
Partner 2 should then
git add
the file andgit commit
. -
If Partner 2 tries to
git push
, they should see an error message something like this:$ git push To https://github.com/droberts-ada/git-pull-activity.git ! [rejected] master -> master (non-fast-forward) error: failed to push some refs to 'https://github.com/droberts-ada/git-pull-activity.git' hint: Updates were rejected because a pushed branch tip is behind its remote hint: counterpart. Check out this branch and integrate the remote changes hint: (e.g. 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Git won't let you push if there are changes on the server that you don't have locally. This is a good thing! It reduces the chance of something going wrong.
-
Partner 2 should now
git pull
. These two changes should be compatible, but git will still need to do some work to put them together. Like any other piece of work, the merge needs to have a commit, so git will open up ask for a commit message. The default message is perfect, and it's standard to accept the default commit message. Finishing this commit message will allow the pull process to finish-- you have completed pulling thegit pull
(fetch and merge) command with this! -
After doing a merge, it's always wise to check git's work. Partner 2 should open up the file and verify that the two commits were merged cleanly. Both methods should be uncommented. In the real world, you would run your tests and make sure nothing broke.
-
Partner 2 is now free to push their work to GitHub.
As clever as Git may be, sometimes there's not an obvious right way to merge two changes. This situation is called a merge conflict. In this case the only way forward is for a human to do the merge by hand.
Task 4
demonstrates a merge conflict. Instructions are as follows:
-
Partner 1: Change the
clock_noise
method toputs "tick"
, save, add, commit and push. -
Partner 2: Before pulling, change
clock_noise
toputs "tock"
, and save, add and commit. -
Partner 2: Try to push. As before, git should warn you that your local copy is out of date.
-
Partner 2: Now run
git pull
. Git should tell you that there's a merge conflict! It has also modifiedpull_practice.rb
to tell you what the conflict is. Theclock_noise
method should now read as follows:def clock_noise <<<<<<< HEAD puts "tock" ======= puts "tick" >>>>>>> master end
Git has included both versions of the method, and labeled where they came from.
HEAD
is the local copy, andmaster
is the version from GitHub. -
Partner 2: Work with your partner to resolve the conflict.
-
Using VS Code, pick which of the versions you want to use, and remove all the extra stuff that GitHub added. The end result should be valid ruby code.
def clock_noise puts "tick tock" end
-
Use
git add pull_practice.rb
to mark the conflict as resolved. -
Use
git commit
to finish the merge.
-
-
Partner 2: Is now free to push their work to GitHub.
This one was simple, but in the real world merge conflicts can get really hairy. But as weird as it can be, without git collaboration would be a thousand times more difficult. We'll talk more about resolving merge conflicts in another lecture.