Lab 9 - Version Control and Backups

Git IRL

Fixing mistakes

If you ever feel like you need to start over, you can run these commands:

git checkout master
git reset --hard b9_start

And if you created the branch my_branch, delete it with

git branch -D my_branch

Pulling the code

To clone the decal-lab git repository, run: git clone https://github.com/0xcf/decal-labs.git

If you have already cloned the repository, go to your decal-labs directory and run git pull to pull the latest changes. The materials for this part of the lab will be in the b9 directory.

Also if you dont have make installed, run the following command: sudo apt install make

Making changes

When making modifications to a repository, the best practice is to create a new branch for your changes. To do this, run git checkout -b my_branch. This command will create a new branch and switch to it.

Now we will make a modification to some_code.c and commit it. Change line 4 to char *x = "Correct output"; and save. Now run

make
./some_code

This should output Correct output on the console. Now stage your changes and make a new commit with a message saying “Added Correct output” (hint: lecture slide 6).

Now we’re going to add another feature to some_code.c. Under the comment on line 7, add the following code:

char* feature = "Here's my new feature!";
puts(feature);

Now again run

make
./some_code

And check that the output is “Correct output” followed by “Heres my new feature!”. Now stage and commit these changes with the message “Added my new feature”.

Simulating change over time

Typically while you work on a branch, people will add modifications to the main codebase, such as bugfixes. Lets simulate what this would look like.

First, checkout the master branch with git checkout master. Next, in some_code.c, change line 4 to char *x = "Changed output";. Save this and run

make
./some_code

Which should output “Changed output”. Now stage and commit these changes with the message “Added changed output”.

Including your changes

Typically we create a new branch so we can add a logically associated set of features to the codebase. Now that we’ve completed and tested this set of features, we want to include our changes into the main repository. Typically there are two methods of doing this, merging and rebasing. Some people (including the OCF) prefer rebasing because it results in an easier to read commit history, so that’s what we’ll do.

We will be rebasing our changes on top of the master branch. First, switch back to your testing branch with git checkout my_branch. Now run git rebase master to begin the rebase. You’ll notice that there seems to be a merge conflict, we’ll have to resolve this before we can complete the rebase.

Whenever we attempt to join the history of different branches either through merging or rebasing, we can run into merge conflicts. These need to be resolved by manual intervention.

The conflicted zone in a file follows the following format:

<<<<<<< HEAD
Line in the base tree
=======
Same line in your file that you're joining with base
>>>>>>> my_branch

To fix the conflict, you must remove all lines in the conflicting zone except the line you would like to keep.

Modify some_code.c to fix the merge conflict. We want to keep the line that says “Correct output”. Once this is done, save and run git add some_code.c to resolve the merge conflict. Refer to the reference section below for an explanation on resolving merge conflicts.

Now that the merge conflict is fixed, we can continue the rebase by running git rebase --continue. Now the rebase should be complete. Confirm by running git log. This should print out something like

commit 10e9bc0edefbf280f2dbcd100d1479f3d8773d6c (HEAD -> test)
Author: William Porr <wporr@nvidia.com>
Date:   Mon Oct 28 18:57:12 2019 -0700

    Added my new feature

commit cbe253d523c12f05595b8d84d7195cb728718967
Author: William Porr <wporr@nvidia.com>
Date:   Mon Oct 28 18:55:51 2019 -0700

    Added correct output

commit 6e14391676dc6213cc6f4e186dcb88f3edf84994 (master)
Author: William Porr <wporr@nvidia.com>
Date:   Mon Oct 28 18:58:00 2019 -0700

    Added changed output

commit b9a2169e7d53d7a30ae933e09aeb8e8245117c0c
Author: William Porr <wporr@nvidia.com>
Date:   Mon Oct 28 18:43:21 2019 -0700

    Added b9 code

Now that our branch has a clean history, we can merge it with the master branch. This is where you would normally submit a pull request on github or some other shared git interface, but we’re just going to merge the branch ourselves. Switch to the master branch with git checkout master and run git merge my_branch to merge your branch into master.

Cleaning up

Now that your change is rebased, you can delete your branch with git branch -D my_branch

Questions

  1. What caused the merge conflict in the git exercises you did?

  2. Why does git require us to manually intervene in merge conflicts?

  3. What command would you use to sync a folder ~/Downloads/Linux_ISOs to the folder /usr/local/share/Calendar, while preserving file metadata? (hint: use rsync)

  4. How does rsync determine when to look for changes between files? Select from the following:

    A. By calculating the checksum of each file and comparing them.

    B. By comparing the entire contents of each file for any differences.

    C. By seeing if the ‘last modified’ timestamp of the files are different.

    D. By seeing if the ‘created’ timestamp of the files are different.

    E. By seeing if the permissions of the files are different.

  5. Consider a file str1 containing the string ‘abcd’. You rsync it to another file str2, and then replace ‘abcd’ with ‘aaaa’ on str1. If you run ‘rsync –append str1 str2’, what will the contents of str2 be?