Assignment 1: Pigs
version: 1.3 last updated: 20220704 930
This assignment aims to give you
practice in Shell programming generally
a clear concrete understanding of Gits 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 online 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.
Introduction
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.
Reference implementation
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 pigsadd should match the behaviour of 2041 pigsadd exactly, including producing
the same error messages.
Provision of a reference implementation is a common method to provide or define an operational specification, and
its something you will likely need to do after you leave UNSW.
Discovering and matching the reference implementations behaviour is deliberately part of the assignment.
While the code in the reference implementation is fairly straightforward, reverseengineering 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 implementations behaviour in this case.
Pigs Commands
Subset 0 commands must be implemented in POSIXcompatible Shell.
See the Permitted Languages section for more information.
https:en.wikipedia.orgwikiGit
The pigsinit command creates an empty Pigs repository.
pigsinit 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: cannot access .pig: No such file or directory
Initialized empty pigs repository in .pig
.pigsinit: error: .pig already exists
pigsinit 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
pigsadd filenames…
The pigsadd command adds the contents of one or more files to the index.
Files are added to the repository in a twostep process. The first step is adding them to the index.
You will need to store files in the index somehow in the .pig subdirectory.
For example, you might choose store them in a subdirectory of .pig .
Only ordinary files in the current directory can be added.
You can assume filenames start with an alphanumeric character azAZ09 and will only contain alphanumeric
characters, plus . , and characters.
The pigsadd command, and other Pigs commands, will not be given pathnames with slashes.
pigscommit m message
The pigscommit 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 newline characters, and does not start with a
character.
The pigslog command prints a line for every commit made to the repository.
Each line should contain the commit number and the commit message.
pigsshow commit:filename
The pigsshow 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 nonnegative integer.
Subset 0 examples
Initialized empty pigs repository in .pig
echo line 1 a
echo hello world b
.pigsadd a b
.pigscommit m first commit
Committed as commit 0
echo line 2 a
.pigsadd a
.pigscommit m second commit
Committed as commit 1
1 second commit
0 first commit
echo line 3 a
.pigsadd a
echo line 4 a
.pigsshow 0:a
.pigsshow 1:a
Subset 1 is more difficult. You will need to spend some time understanding the semantics meaning of these
operations, by running the reference implementation, or researching the equivalent Git operations.
Note the assessment scheme recognises this difficulty.
Subset 1 commands must be implemented in POSIXcompatible Shell.
See the Permitted Languages section for more information.
pigscommit a m message
pigscommit can now have a a option,
which causes all files already in the index to have their contents from the current directory added to the index before
the commit.
pigsrm force cached filenames…
pigsrm removes a file from the index, or, from the current directory and the index.
If the cached option is specified, the file is removed only from the index, and not from the current directory.
pigsrm , like git rm , should stop the user accidentally losing work, and should give an error message instead if
the removal would cause the user to lose work. You will need to experiment with the reference implementation to
discover these error messages. Researching git rm s behaviour may also help.
The force option overrides this, and will carry out the removal even if the user will lose work.
pigsstatus
pigsstatus shows the status of files in the current directory, the index, and the repository.
There are many different cases to consider for pigsstatus .
You will need to experiment with the reference implementation to find them all.
Subset 1 examples
Initialized empty pigs repository in .pig
touch a b c d e f g h
.pigsadd a b c d e f
.pigscommit m first commit
Committed as commit 0
echo hello a
echo hello b
.pigscommit a m second commit
Committed as commit 1
echo world a
echo world b
echo hello world c
.pigsadd a
echo world b
.pigsadd g
.pigsstatus
a file changed, changes staged for commit
b file changed, changes not staged for commit
Subset 2 is extremely difficult. You will need to spend considerable time understanding the semantics of these
operations, by running the reference implementation, andor researching the equivalent Git operations.
Note the assessment scheme recognises this difficulty.
Subset 2 commands must be implemented in POSIXcompatible Shell.
See the Permitted Languages section for more information.
pigsbranch d branchname
pigsbranch either creates a branch, deletes a branch, or lists current branch names.
If branchname is omitted, the names of all branches are listed.
If branchname is specified, then a branch with that name is created or deleted,
depending on whether the d option is specified.
pigscheckout branchname
pigscheckout switches branches.
Note that, unlike Git, you can not specify a commit or a file: you can only specify a branch.
pigsmerge branchnamecommitnumber m message
pigsmerge adds the changes that have been made to the specified branch or commit to the index, and commits
Subset 2 examples
Initialized empty pigs repository in .pig
seq 1 7 7.txt
.pigsadd 7.txt
.pigscommit m commit1
Committed as commit 0
.pigsbranch b1
.pigscheckout b1
Switched to branch b1
sed Ei s242 7.txt
.pigscommit a m commit2
Committed as commit 1
.pigscheckout master
If a file has been changed in both branches pigsmerge produces an error message.
Note: if a file has been changed in both branches git examines which lines have been changed and combines the
changes if possible. Pigs doe not do this, for example:
Initialized empty pigs repository in .pig
seq 1 7 7.txt
.pigsadd 7.txt
.pigscommit m commit1
Committed as commit 0
.pigsbranch b1
.pigscheckout b1
Switched to branch b1
sed Ei s242 7.txt
.pigscommit a m commit2
Committed as commit 1
.pigscheckout master
As usual, some autotests will be available:
2041 autotest pigs pigs
You can also run only tests for a particular subset or an individual test:
2041 autotest pigs subset1 pigs
2041 autotest pigs subset113 pigs
If you are using extra Shell files, include them on the autotest command line.
Autotest and automarking will run your scripts with a current working directory different to the directory containing
the script. The directory containing your submission will be in PATH .
You will need to do most of the testing yourself.
Test Scripts
You should submit ten Shell scripts, named test00.sh to test09.sh , which run pigs commands that test an
aspect of Pigs.
The test??.sh scripts do not have to be examples that your program implements successfully.
You may share your test examples with your friends, but the ones you submit must be your own creation.
The test scripts should show how youve thought about testing carefully.
You are only expected to write test scripts testing parts of Pigs you have attempted to implement. For example, if you
have not attempted subset 2 you are not expected to write test scripts testing pigsmerge .
Permitted Languages
Your programs must be written entirely in POSIXcompatible shell.
Your programs will be run with dash, in bindash . You can assume anything that works with the version of
bindash on CSE systems is POSIX compatible.
Start your programs with:
If you want to run these scripts on your own machine for example, one running macOS which has dash installed
somewhere other than bin , use:
!usrbinenv dash
You are permitted to use any feature bindash provides.
On CSE systems, binsh is the Bash Bourneagain shell shell: binsh is a symlink to binbash . Bash
implements many nonPOSIX extensions, including regular expressions and arrays. These will not work with
bindash , and you are not permitted to use these for the assignment.
You are not permitted to use Perl, Python or any language other than POSIXcompatible shell.
You are permitted to use only these external programs:
https:manpages.debian.orgjump?qdash.1
https:manpages.debian.orgjump?qdash.1
https:manpages.debian.orgjump?qbasename.1
https:manpages.debian.orgjump?qbunzip2.1
https:manpages.debian.orgjump?qbzcat.1
https:manpages.debian.orgjump?qbzip2.1
https:manpages.debian.orgjump?qcat.1
https:manpages.debian.orgjump?qchmod.1
https:manpages.debian.orgjump?qcmp.1
https:manpages.debian.orgjump?qcombine.1
https:manpages.debian.orgjump?qcp.1
https:manpages.debian.orgjump?qcpio.1
https:manpages.debian.orgjump?qcsplit.1
https:manpages.debian.orgjump?qcut.1
https:manpages.debian.orgjump?qdate.1
https:manpages.debian.orgjump?qdc.1
https:manpages.debian.orgjump?qdd.1
https:manpages.debian.orgjump?qdf.1
https:manpages.debian.orgjump?qdiff.1
https:manpages.debian.orgjump?qdirname.1
https:manpages.debian.orgjump?qdu.1
https:manpages.debian.orgjump?qecho.1
https:manpages.debian.orgjump?qegrep.1
https:manpages.debian.orgjump?qenv.1
https:manpages.debian.orgjump?qexpand.1
https:manpages.debian.orgjump?qexpr.1
https:manpages.debian.orgjump?qfalse.1
https:manpages.debian.orgjump?qfgrep.1
https:manpages.debian.orgjump?qfind.1
https:manpages.debian.orgjump?qfold.1
https:manpages.debian.orgjump?qgetopt.1
https:manpages.debian.orgjump?qgetopts.1
https:manpages.debian.orgjump?qgrep.1
https:manpages.debian.orgjump?qgunzip.1
https:manpages.debian.orgjump?qgzip.1
https:manpages.debian.orgjump?qhead.1
https:manpages.debian.orgjump?qhostname.1
https:manpages.debian.orgjump?qifne.1
https:manpages.debian.orgjump?qless.1
https:manpages.debian.orgjump?qln.1
https:manpages.debian.orgjump?qls.1
https:manpages.debian.orgjump?qlzcat.1
https:manpages.debian.orgjump?qlzma.1
https:manpages.debian.orgjump?qmd5sum.1
https:manpages.debian.orgjump?qmkdir.1
https:manpages.debian.orgjump?qmktemp.1
https:manpages.debian.orgjump?qmore.1
https:manpages.debian.orgjump?qmv.1
https:manpages.debian.orgjump?qnl.1
https:manpages.debian.orgjump?qpatch.1
https:manpages.debian.orgjump?qprintf.1
https:manpages.debian.orgjump?qpwd.1
https:manpages.debian.orgjump?qreadlink.1
https:manpages.debian.orgjump?qrealpath.1
https:manpages.debian.orgjump?qrev.1
https:manpages.debian.orgjump?qrm.1
uncompress
Only a few of the programs in the above list are likely to be useful for the assignment.
Note you are permitted to use builtin shell features including: cd , exit , for , if , read , shift and while .
If you wish to use an external program which is not in the above list, please ask in the class forum for it to be added.
You may submit extra shell files.
AssumptionsClarifications
Like all good programmers, you should make as few assumptions as possible.
You can assume pigs commands are always run in the same directory as the repository, and only files from that
directory are added to the repository.
You can assume the directory in which pigs commands are run will not contain subdirectories apart from .pig .
You can assume where a branch name is expected a string will be supplied starting with an alphanumeric character
azAZ09, and only containing alphanumeric characters plus and . In addition a branch name will not be
supplied which is entirely numeric. This allows brnach names to be distinguished from commits when merging.
You can assume where a filename is expected a string will be supplied starting with an alphanumeric character a
zAZ09 and only containing alphanumeric characters, plus ., and characters.
You can assume where a commit number is expected a string will be supplied which is a nonnegative integer with
no leading zeros. It will not contain white space or any other charcters except digits.
You can assume that pigsadd , pigsshow , and pigsrm will be given just a filename, not pathnames with
You do not have to consider file permissions or other file metadata. For example, you do not have to ensure files
created by a checkout command have the same permissions as when they were added.
You do not have to handle concurrency. You can assume only one instance of any pigs command is running at any
You can assume that only the arguments described above are supplied to pigs commands. You do not have to
handle other arguments.
You should match the output streams used by the reference implementations. It writes error messages to stderr: so
should you.
You should match the exit status used by the reference implementation. It exits with status 1 after an error: so should
You can assume the directory containing your scripts is in PATH .
You can not assume the directory containing your scripts is the same as the repo.
Your scripts are always run in the directory containing the repository.
Autotests and automarking will put your scripts pigsinit, pigsadd, … in a different directory to the repository. This
may break scripts which run or source other scripts or file and assume they are in the current directory. Autotests
https:manpages.debian.orgjump?qrmdir.1
https:manpages.debian.orgjump?qsed.1
https:manpages.debian.orgjump?qseq.1
https:manpages.debian.orgjump?qsha1sum.1
https:manpages.debian.orgjump?qsha256sum.1
https:manpages.debian.orgjump?qsha512sum.1
https:manpages.debian.orgjump?qsleep.1
https:manpages.debian.orgjump?qsort.1
https:manpages.debian.orgjump?qsponge.1
https:manpages.debian.orgjump?qstat.1
https:manpages.debian.orgjump?qstrings.1
https:manpages.debian.orgjump?qtac.1
https:manpages.debian.orgjump?qtail.1
https:manpages.debian.orgjump?qtar.1
https:manpages.debian.orgjump?qtee.1
https:manpages.debian.orgjump?qtest.1
https:manpages.debian.orgjump?qtime.1
https:manpages.debian.orgjump?qtop.1
https:manpages.debian.orgjump?qtouch.1
https:manpages.debian.orgjump?qtr.1
https:manpages.debian.orgjump?qtrue.1
https:manpages.debian.orgjump?quname.1
https:manpages.debian.orgjump?quncompress.1
https:manpages.debian.orgjump?qunexpand.1
https:manpages.debian.orgjump?quniq.1
https:manpages.debian.orgjump?qunlzma.1
https:manpages.debian.orgjump?qunxz.1
https:manpages.debian.orgjump?qunzip.1
https:manpages.debian.orgjump?qwc.1
https:manpages.debian.orgjump?qwget.1
https:manpages.debian.orgjump?qwhich.1
https:manpages.debian.orgjump?qwho.1
https:manpages.debian.orgjump?qxargs.1
https:manpages.debian.orgjump?qxz.1
https:manpages.debian.orgjump?qxzcat.1
https:manpages.debian.orgjump?qyes.1
https:manpages.debian.orgjump?qzcat.1
and automarking will add the directory containing your scripts to PATH . This allows you to access other scripts or
files by just specifying their name. For example: . libraryfunctions.sh will source the shell commands in
. libraryfunctions.sh even though it is another directory, because the directory has been added to PATH .
Note running . .libraryfunctions.sh will break during autotests and automarking. There can be subtle
problem related to directories, ask for help in the forum.
You can assume arguments will be in the position and order shown in the usage message from the reference
implementation. Other orders and positions will not be tested. For example, here is the usage message for pigsrm :
2041 pigsrm
usage: pigsrm force cached filenames
So, you assume that if the force or cached options are present, they come before all filenames, and if they
are both present the force option will come first.
Pigs error messages include the program name. It is recommended you use 0 however it is also acceptable to
hardcode the program name. The automarking and style marking will accept both.
Do not use the modification time of a file to determine whether it has changed. You must use the file contents.
Change Log
Assessment
When you think your program is working, you can use autotest to run some simple automated tests:
2041 autotest pigs
2041 autotest will not test everything.
Always do your own testing.
Automarking will be run by the lecturer after the submission deadline, using a superset of tests to those autotest
runs for you.
Submission
When you are finished working on the assignment, you must submit your work by running give :
Version 1.0
20220621 1200
Initial release
Version 1.1
20220623 2300
Reference Update pigstatus to include a usage message
Version 1.2
20220629 130
Reference Update pigsbranch to give an error message when the current
branch is deleted
ReferenceAutotest Update pigsbranch to give a better error message when
the default branch is deleted
Version 1.3
20220704 930
Reference Fixed pigscommit a failing when trying to remove the last file in
Reference Update pigsshow to display a usage message when the first
argument is not in the correct format
ReferenceAutotest Update pigstatus to show better status when a file is
removed from the index
give cs2041 ass1pigs pigs test??.sh anyotherfiles
You must run give before Week 7 Monday 115959 2023 midday to obtain the marks for this assignment.
Note that this is an individual exercise, the work you submit with give must be entirely your own.
You can run give multiple times.
Only your last submission will be marked.
If you are working at home, you may find it more convenient to upload your work via gives web interface.
You cannot obtain marks by emailing your code to tutors or lecturers.
You can check your latest submission on CSE servers with:
2041 classrun check ass1pigs
You can check the files you have submitted here.
Manual marking will be done by your tutor, who will mark for style and readability, as described in the Assessment
section below. After your tutor has assessed your work, you can view your results here; The resulting mark will also
be available via gives web interface.
This assignment is due Week 7 Monday 115959 2023 midday 20230710 115900.
The UNSW standard late penalty for assessment is 5 per day for 5 days this is implemented hourly for this
assignment.
Your assignment mark will be reduced by 0.2 for each hour or part thereof late past the submission deadline.
For example, if an assignment worth 60 was submitted half an hour late, it would be awarded 59.8, whereas if it
was submitted past 10 hours late, it would be awarded 57.8.
Beware submissions 5 or more days late will receive zero marks. This again is the UNSW standard assessment
Assessment Scheme
This assignment will contribute 15 marks to your final COMP20419044 mark
15 of the marks for assignment 1 will come from handmarking. These marks will be awarded on the basis of clarity,
commenting, elegance and style: in other words, you will be assessed on how easy it is for a human to read and
understand your program.
5 of the marks for assignment 1 will be based on the test suite you submit.
80 of the marks for assignment 1 will come from the performance of your code on a large series of tests.
An indicative assessment scheme follows. The lecturer may vary the assessment scheme after inspecting the
assignment submissions, but it is likely to be broadly similar to the following:
HD 85 All subsets working; code is beautiful; great test suite
DN 75 Subset 1 working; good clear code; good test suite
CR 65 Subset 0 working; good clear code; good test suite
PS 55 Subset 0 passing some tests; code is reasonably readable;
reasonable test suite
PS 50 Good progress on assignment, but not passing autotests
https:cgi.cse.unsw.edu.augiveStudentgive.php
https:cgi.cse.unsw.edu.aucs204123T2student
https:cgi.cse.unsw.edu.aucs204123T2student
https:cgi.cse.unsw.edu.augiveStudentsturec.php
COMP20419044 23T2: Software Construction is brought to you by
the School of Computer Science and Engineering
at the University of New South Wales, Sydney.
For all enquiries, please email the class account at
CRICOS Provider 00098G
0 knowingly providing your work to anyone
and it is subsequently submitted by anyone.
COMP20419044
submitting any other persons work; this includes joint work.
misconduct
submitting another persons work without their consent;
paying another person to do work for you.
Intermediate Versions of Work
You are required to submit intermediate versions of your assignment.
Every time you work on the assignment and make some progress you should copy your work to your CSE account
and submit it using the give command below. It is fine if intermediate versions do not compile or otherwise fail
submission tests. Only the final submitted version of your assignment will be marked.
Attribution of Work
This is an individual assignment.
The work you submit must be entirely your own work, apart from any exceptions explicitly included in the assignment
specification above. Submission of work partially or completely derived from any other person or jointly written with
any other person is not permitted.
You are only permitted to request help with the assignment in the course forum, help sessions, or from the teaching
staff the lecturers and tutors of COMP20419044.
Do not provide or show your assignment work to any other person including by posting it on the forum, apart from
the teaching staff of COMP20419044. If you knowingly provide or show your assignment work to another person
for any reason, and work derived from it is submitted, you may be penalized, even if that work was submitted without
your knowledge or consent; this may apply even if your work is submitted by a third party unknown to you. You will
not be penalized if your work is taken without your consent or knowledge.
Do not place your assignment work in online repositories such as github or anywhere else that is publicly accessible.
You may use a private repository.
Submissions that violate these conditions will be penalised. Penalties may include negative marks, automatic failure
of the course, and possibly other academic discipline. We are also required to report acts of plagiarism or other
student misconduct: if students involved hold scholarships, this may result in a loss of the scholarship. This may also
result in the loss of a student visa.
Assignment submissions will be examined, both automatically and manually, for such submissions.
https:www.cse.unsw.edu.au
https:www.unsw.edu.au