W1007.20 Merging

From Coder Merlin

Prerequisites[edit]

Introduction[edit]

Research[edit]

Version Control (Wikipedia) Introduction to Version Control (Emacs)

Experiment[edit]

Note: You will need to work with a partner for this lab. (We'll call the partners, Partner A and Partner B.)

WarnIcon.png
Caution

Throughout this exercise (and all exercises, and life in general) always use your own credentials, DO NOT SHARE YOUR CREDENTIALS WITH ANYONE. Each partner should always use their own username and their own password.

First Steps[edit]

Only Partner A should perform the following steps:

Log on to GitHub
Click on New next to "Repositories" New Repository
On the next page:
  1. Enter "TheStory" as the Repository name
  2. Select Private
  3. Select Initialize this repository with a README
  4. Click on Create repository
Create New Repository
At the top of the next page, click on Settings Settings
On the left-hand list, select Collaborators Collaborators
On the right-hand side:
  1. Enter the GitHub user name of Partner B's GitHub account
  2. Click the Add collaborator button
  3. Enter the GitHub user name of your invigilator
  4. Click the Add collaborator button
Collaborators

Only Partner B should perform the following steps:

Partner B will receive an invitation email from GitHub.
  1. Partner B should open the email. If it doesn't appear to arrive within a minute or two check the SPAM/Junk folder.
  2. Partner B should click on the Accept Invitation link.
Accept Invitation
If Partner B sees the image on the right he/she should log in to GitHub and then click on the link in the email again. Not Found

Both Partners[edit]

Both partners should now log on to the server.

Create a project directory:

cd ~/projects
mkdir project-1063
cd project-1063
WarnIcon.png
Caution
Do not skip this step! In order to successfully complete the remainder of the lab, it's important that your username and password (credentials) for GitHub are saved for future access. You can accomplish this by following the steps here and then continuing with this project.

Next, both partners should clone the newly created repository. Note that the actual name of the repository will depend on the user name of Partner A. Adjust the URL appropriately by replacing PARTNER_A_USER_NAME with the actual Partner A user name.

 git clone https://github.com/PARTNER_A_USER_NAME/TheStory

Depending on your configuration, you may need to enter your username and password for GitHub. However, after this point, your credentials should be cached and you shouldn't need to enter them again and again.

Now, enter the directory and then pull the contents from the repository.

cd TheStory
git pull

Partner B on the Command Line[edit]

Partner B should now perform the following:

  1. Create a new file, "story.txt", with emacs:
emacs story.txt

Next, copy and paste the following text into the file. Then, save the file and exit.

Whilst we were talking, we heard a sort of sound between a
yelp and a bark. It was far away; but the horses got very restless,
and it took Johann all his time to quiet them. He was pale and said,
"It sounds like a wolf - but yet there are no wolves here now."
"No?" I said, questioning him. "Isn't it long since the wolves were
so near the city?"

Check the status of your local git repository by typing:

git status
Question Mark Icon - Blue Box
After carefully reading the output text of the command, why do you think "story.txt" is listed as "untracked"?

In order to track the file, type:

git add story.txt
HintIcon.png
Helpful Hint
If you need to add multiple files there's no need to issue the command multiple times. Just list the files one after another, separated by a space.

Check the status again:

git status
Question Mark Icon - Blue Box
After carefully reading the output text of the command, why do you think "story.txt" is listed as "new file"?

In order to commit your changes to your local repository, type:

git commit

Emacs will open enabling you to type a description of what you've changed (added, modified, deleted). This should be a useful message. For ideas about how to ensure that your message is useful, read The Art of the Commit (by David Demaree). After entering your message, save and exit emacs as usual.

Check the status again:

git status
Question Mark Icon - Blue Box
After carefully reading the output text of the command, what do you think is meant by "Your branch is ahead of 'origin/master' by 1 commit"?

Let's push the changes to the remote repository:

git push

Verify that your changes are visible on GitHub by going to the same URL that you used for the git clone operation.

Partner A on the Command Line[edit]

Partner A can now receive the changes made by Partner B. To do so, Partner A should execute:

git pull

To check the directory contents, execute:

ls

Open the file in emacs:

emacs story.txt

Next, copy and paste the following text to the end of the file. Then, save the file and exit.

"Long, long," he answered, "in the spring and summer; but with
the snow the wolves have been here not so long."

What changed from the previous commit? Have a look with:

git diff

Now, check the status:

git status
Question Mark Icon - Blue Box
After carefully reading the output text of the command, why do you think "story.txt" is shown in red as "modified"?

Now, use git to add, commit, and push your changes to your remote repository on GitHub.

Partner B in Emacs[edit]

Partner B can now receive the changes made by Partner A, but let's be smarter and use the features available from within emacs.

Start emacs, opening "story.txt".

Question Mark Icon - Blue Box
Pay close attention to the mode line in emacs. In addition to your file's name, is there any indication that this file is under source control?

Pull the latest changes from the remote GitHub repository. There's no need to exit emacs; emacs contains a built-in client for interacting with many source control systems. Enter the sequence: C-x v +

Emacs has now executed git pull and displayed the results in a separate window. You'll note that the text in the window indicates that "story.txt" was changed. You may also note that the buffer (for story.txt) hasn't yet changed. In order to refresh the buffer, type M-x revert-buffer and answer "yes". (Don't worry! If you forget to do this emacs will warn you.)

Add the following text to the end of the file:

Whilst he was petting the horses and trying to quiet them, dark
clouds drifted rapidly across the sky. The sunshine passed away,
and a breath of cold wind seemed to drift over us. It was only a
breath, however, and more of a warning than a fact, for the sun
came out brightly again.

Save the file with C-x s

Within emacs, we can check for differences between the version in the local repository and our uncommitted changes by typing C-x v =

Remember, that to close a window in emacs, with the cursor in that window, type C-x 0 (the last character is a zero). Close the diff window now.

Add and commit this change of adding the third paragraph by typing C-x v v. A new window will open asking you to type in a check-in comment. Do so and then type C-c C-c to exit that window.

To view a log of changes, type C-x v l (the last character is a lowercase L). You can scroll through the log in the same way that you scroll through any other buffer in emacs.

At this point, we've modified the file, added it to our local repository and committed it, but we haven't yet pushed it to the remote repository. We can do that by typing C-x v P

HintIcon.png
Helpful Hint
If you have several windows open but only care about one you can go to that window (using one or more C-x o) and then typing C-x 1 (that's the digit one)


HintIcon.png
Helpful Hint
There are many version-control commands. If you forget the key-sequence you can look it up with C-x v ?

Partner A in Emacs[edit]

Partner A should begin, as always, by pulling any remote changes. Begin by opening emacs to edit "story.txt". Then, pull any remote changes with C-x v +

If a change is detected, remember to execute M-x revert-buffer and confirm the change.

HintIcon.png
Helpful Hint
If you find it a hassle to execute "revert-buffer" you can set up emacs to do this for you automatically. See Emacs Power User Tips

Add the following text to the end of the file:

Johann looked under his lifted hand at the horizon and said, "The
storm of snow, he comes before long time." Then he looked at his
watch again, and, straightway holding his reins firmly - for the
horses were still pawing the ground restlessly and shaking their
heads - he climbed to his box as though the time had come for
proceeding on our journey.

Now, save the file with C-x s. Then, commit the change with C-x v v, adding a commit message, and then typing C-c C-c. But don't push the change just yet!

Partner B Makes Another Change in Emacs[edit]

Remember that Partner A has committed changes to the local repository but hasn't yet pushed them. What happens if Partner B makes and pushes a change before Partner A pushes their change?

Partner B should now open emacs to "story.txt" and paste the following text to the end of the file:

Jonathan looked out toward the horizon and said, "The rain, 
she comes before long time." Then he looked at his
watch again, and, holding his reins firmly - for the
horses were still restless and shaking their heads - 
he climbed to his box as though the time had come for
proceeding on our journey.

Now, save the file with C-x s. Then, commit the change with C-x v v, adding a commit message, and then typing C-c C-c. Push the file to the remote repository with C-x v P.

Partner A Tries to Push[edit]

Remember that Partner B pushed his committed changes to the remote repository but Partner A didn't push his changes yet. Let's see what happens if Partner A tries to push now.

Partner A types C-x v P in an attempt to push.

Question Mark Icon - Blue Box
Pay close attention to the output. What does the message mean?

The attempt to push failed because the remote contains changes that we don't have locally. We'll need to get those changes before we can proceed. We can do that the same way that we normally do, with C-x v +.

Question Mark Icon - Blue Box
Pay close attention to the output. What does the message mean?

Note that the message informed us of a merge conflict in file "story.txt". Be sure that your cursor is positioned in that window ("story.txt") and reload the file from disk by typing M-x revert-buffer.

Question Mark Icon - Blue Box
Pay close attention to the text. Note the special symbols at the beginning of three lines: <<<, === and >>>. What do they mean?

Git is telling us that it doesn't know how to automatically merge these changes. In other words, there's a conflict between the changes that Partner A made and the changes that Partner B made that can't be resolved automatically. This isn't bad! It's a natural consequence of working together on the same file and it's easily resolved.

Note that in one file there can be multiple conflicts. In order to navigate easily from conflict to conflict you can use C-c ^ n to move to the next conflict and C-c ^ p to move to the previous conflict. If your cursor isn't already positioned on the conflict, try typing C-c ^ n now and note the highlighting.

At this point, you need to decide if you want to keep your change or the other change. To keep your change you'd use C-c ^ m (keep my change) or C-c ^ o (keep other change). For now, keep your own change, so type C-c ^ m. Type C-x S to save the file.

Now that you've resolved the conflicts you can complete the merge. Temporarily put emacs to sleep with C-z.

On the command line, type git commit. The default message in emacs is often sufficient so you can just type C-x C-c to exit. Your changes have now been committed to the local repository. You can now resume emacs by typing fg.

The last step is to push to the remote. Do so now with C-x v P.

HintIcon.png
Helpful Hint
If you accidentally exit the merge you can easily resume your work by typing M-x smerge-mode


HintIcon.png
Helpful Hint
If you're worried that you really messed up the merge, as a last resort, you can execute git merge --abort on the command line to start over.

Key Concepts[edit]

KeyConceptsIcon.png
Key Concepts
  • Source Control enables us to:
    • Track who changed a file and when
    • View a specific code revision
    • Rollback to a specific code revision
    • Resolve conflicts between source files through a process called merging
  • In this lab you've learned how to use emacs to handle (nearly) all interactions with both the local and remote repositories. You've also learned how emacs can be very helpful at highlighting merge conflicts and in assisting you to resolve them.