This assignment aims to give you
- practice in Shell programming generally
- a clear concrete understanding of Git’s core semantics
Note: the material in the lecture notes will not be sufficient by itself to allow you to complete this assignment. You may need to search on-line
documentation for Shell, Git, etc. Being able to search documentation efficiently for the information you need is a very useful skill for any kind
of computing work.
Your task in this assignment is to implement Pigs, a subset of the version control system Git.
Git is a very complex program that has many individual commands. You will implement only a few of the most important commands. You will
also be given a number of simplifying assumptions, which make your task easier.
Pigs stands for POSIX Implementation of Git in Shell.
As you must implement Pigs in POSIX Shell (dash).
Interestingly, early versions of Git made heavy use of Shell and Perl.
Many aspects of this assignment are not fully specified in this document; instead, you must match the behaviour of a reference implementation.
For example, your script pigs-add should match the behaviour of 2041 pigs-add exactly, including producing the same error messages.
Provision of a reference implementation is a common method to provide or define an operational specification, and it’s something you will
likely need to do after you leave UNSW.
Discovering and matching the reference implementation’s behaviour is deliberately part of the assignment.
While the code in the reference implementation is fairly straightforward, reverse-engineering its behaviour is obviously not so simple, and is a
nice example of how coming to grips with the precise semantics of an apparently obvious task can still be challenging.
If you discover what you believe to be a bug in the reference implementation, report it in the class forum. We may fix the bug, or indicate that
you do not need to match the reference implementation’s behaviour in this case.
Subset 0 commands must be implemented in POSIX-compatible Shell.
See the Permitted Languages section for more information.
The pigs-init command creates an empty Pigs repository.
pigs-init should create a directory named .pig , which it will use to store the repository.
It should produce an error message if this directory already exists, or cannot be created.
You should match this, and other error messages exactly. For example:
$ ls -d .pig
ls: cannot access ‘.pig’: No such file or directory
Initialized empty pigs repository in .pig
$ ls -d .pig
./pigs-init: error: .pig already exists
pigs-init may create initial files or directories inside .pig .
You do not have to use a particular representation to store the repository.You do not have to (and should not) create the same files and directories inside .pig as the reference implementation.
You can create whatever files or directories inside .pig you wish.
Do not store information outside .pig
The pigs-add command adds the contents of one or more files to the “index”.
Files are added to the repository in a two-step process. The first step is adding them to the index.
You will need to store files in the index somehow in the .pig sub-directory.
For example, you might choose store them in a sub-directory of .pig .
Only ordinary files in the current directory can be added.
You can assume filenames start with an alphanumeric character ( [a-zA-Z0-9] ) and will only contain alpha-numeric characters, plus . , – and
The pigs-add command, and other Pigs commands, will not be given pathnames with slashes.
pigs-commit -m message
The pigs-commit command saves a copy of all files in the index to the repository.
A message describing the commit must be included as part of the commit command.
Pigs commits are numbered sequentially: they are not hashes, like Git. You must match the numbering scheme.
You can assume the commit message is ASCII, does not contain new-line characters, and does not start with a – character.
The pigs-log command prints a line for every commit made to the repository.
Each line should contain the commit number and the commit message.
The pigs-show should print the contents of the specified filename as of the specified commit.
If commit is omitted, the contents of the file in the index should be printed.
You can assume the commit, if specified, will be a non-negative integer.