uibk_703807-Advanced-CXX/assignment1
2020-09-29 13:37:04 +02:00
..
lit-test Rewording 2020-09-29 13:37:04 +02:00
README.md Rewording 2020-09-29 13:37:04 +02:00

Assignment 1 (draft)

due on 18 November 2020

In this first assignment you are tasked to create a very basic version control system (VCS) similar to Git or Mercurial.

For this assignment you are not allowed to work in teams. You are not allowed to use code from other people participating in this course. Always state the origin of non-original code and ideas.

It is recommend to be familiar Git to understand the intensions behind the following commands.

lit

All functionality of your VCS is bundled into one executable named lit. Similar to git, it provides multiple sub-commands like checkout and status. These sub-commands are always provided as first argument to lit and explained below.

lit help

Displays a concise usage information. Each sub-command is listed and described briefly.

lit init

To initialize a repository run lit init inside some directory. This directory is now the root of the repository. Additionally, the VCS creates a new folder .lit containing all internal data.

All files of the directory are tracked. There is no need to explicitly add them as you'd do with Git.

lit status

Lists all files that have been added, removed, or modified, with respect to the currently checked out commit.

Keep the output concise, similar to git status --short.

lit commit

Creates a new commit containing all changes. In contrast to Git, there is no staging area.

A commit is comprised of a unique identifier, the identifier of the previous commit, a timestamp, a message, and the recorded changes. The message is provided to the commit sub-command as additional argument.

As unique identifier use a counter (starting from 0) and prefix the value with r (for revision).

$ lit commit 'Commit message goes here'
Commit: r42
Date: Mon Sep 28 23:27:53 CEST 2020

lit show

This sub-command is used to inspect the given commit. If no commit is specified, display the currently checked out one.

$ lit show r42
Commit: r42
Date: Mon Sep 28 23:27:53 CEST 2020

Commit message goes here

--- a/Assets/Generic/Logic/Utils/Math.cs
+++ b/Assets/Generic/Logic/Utils/Math.cs
@@ -1,5 +1,10 @@
 using UnityEngine;

+static class Vector2Extensions
+{
+    public static Vector3 AsVector3(this Vector2 v) => new Vector3(v.x, v.y);
+}
+
 static class Vector3Extensions
 {
     public static Vector2 AsVector2(this Vector3 v) => new Vector2(v.x, v.y);

lit checkout

This resets the state of all files to the given commit's state. All un-commited changes are dropped upon checkout.

If no commit is specified, reset the current state to the currently checked out commit.

You can add new branches by first checking out a previous commit, and then creating a new commit.

lit merge

This command initiates a merge with the currently checked out commit and the specified commit. A merge is only initiated if there are no un-commited changes.

Auto-merging files that have been touched in both branches is not supported. If a file has been modified in both branches, the whole file is treated as a conflict.

If a conflict is encountered, stop the merge process and provide the respective files of the other branch as well as the common base.

$ lit merge r1
Merge conflict(s) detected:
    - robot.c

$ ls
robot.c       # currently checked out version.
robot.c.r1    # version of the other branch
robot.c.r0    # common base of both branches

# Manually resolving the merge conflict:
$ vimdiff robot.c robot.c.r1 robot.c.r0

# Cleanup
$ rm robot.c.r1 robot.c.r0

$ lit commit

To complete the merge after manually resolving a conflict, invoke the commit sub-command. To abort the merge, use checkout.

lit log

Displays a graph of all commits, one line per commit. The currently checked out commit is highlighted.

You don't have to follow the exact format of this example:

$ lit log
o─┐ ← r3 "Merge r2 with r1"
│ o   r2 "Add chocolate egg dispenser"
o │   r1 "Add coin operated self destruct feature"
o─┘   r0 "First Commit"

Implementation

You are only allowed to use:

  • C++ standard library (C++17 standard)
  • C standard library (as fallback)
  • POSIX standard library
  • diff / patch command

You must use CMake as build system.

Use ClangFormat to automatically format your code using the provided .clang-format configuration. There is probably a plugin for your text editor / IDE to automate this process.

Your VCS must store the differences (as reported by diff -u). Storing a full copy of the repository's files for each commit is not allowed. You don't need to track empty folders, yet files located in sub-directories.

You may assume that only one instance of your VCS operators on a repository at any point in time. Hence, you don't need to add some form of locking mechanism to prevent concurrent access.

The executable does not depend on any additional resources (except for diff and patch). You may assume that diff and patch are present and available via PATH.

Hint: It may be a good idea to create a dedicated class for invoking shell commands like diff and patch. Simply using system(3) may not give you enough control over the process as you also need to interactive with stdin / stdout. Consider using popen(3) and getting some inspiration from Go's exec package or Python's subprocess module.

Testing

Along with this specification a rudimentary test script lit-test is provided, have a look at it. It assumes that the lit executable is in your path. Remember that you can use bash -x to debug the test script.

You are encouraged to setup some more test cases for your implementation.

Evaluation (9 points)

  • (3) Can create new commits and checkout old ones (no branches)
  • (2) Can create new branches and switch between branches
  • (1) Can inspect a commit using lit show
  • (1) Can merge two branches (no conflict)
  • (1) Can merge two branches (with conflict)
  • (1) Can display a graph with all commits and their relationships

Submission

TBD