Edit ESSENTIAL: Git usage

There are marks dedicated to Git usage. But you could stand to lose more marks in specific assignments also.

If your commits are not frequent, and do not show your progress over the time of the assignment, then you will lose marks.

Whatever your GitHub username is for the very first assignment (namely, Hello GitHub), you should stick to the same GitHub username throughout the course. Otherwise, there might be issues in linking your alternative usernames to your University identity. This means you won’t be getting credit for your work. This also means sticking to the same GitHub account throughout the entire course. It just makes things a lot easier.


(Inadvertent) Tampering with your Git commit history

For obvious reasons, it is not a good idea to tamper with your Git commit history. If you have (even inadvertently) tampered with your commit history, we will be able to tell. This will most likely result in a severe penalty for that assignment.

Sometimes you might feel you “messed up” your commits, and you want to “fix” them. This is not a good idea. However, if you Googled how to “fix” it up, you will likely find some instructions that involve you using (very) dangerous commands, and you should not use them.

As a starting point, any of the following should never be used in assignments for this course:

  • Do not use git push --force
  • Do not use git commit --amend
  • Do not use git reset
  • Do not use git rebase
  • Do not use git squash
  • Or any other similar commands that you might find on the Internet.

All commits must be preserved, including the one that is automatically created by GitHub Classroom, and even ones you think are “bad” or “wrong”. We will not be penalising you for “bad” commits — so keep them in there. We will be penalising you for tampering with your commit history.

The only “editing” command you are allowed to do is git revert (not to be confused with git reset!). This one is fine, because it keeps the original commit history and just adds a new commit that undoes the changes in the previous commit (so, it’s an additional commit on top of the current commit history, as if you had done it manually yourself). Here’s a nice explanation on Stack Overflow.

If you are unsure about anything, please ask us in the Ed Discussion forum before you do anything of this nature.


A recent survey from JetBrains confirms that Git is the version control system technology most used by developers (>93% of the surveyed developers use Git). Besides learning how to use Git, you should also learn the Git etiquette and best practices.

This page includes the Git etiquette and best practices that you should follow in this course.

While we encourage you to follow all of the Git etiquette and best practices discussed on this page, only a subset of them will be marked. To understand the requirements for each release, refer to the table below:

Rule Marked in A1 Marked in A2
Meaningful Commit Messages
Commit Message Length
No Empty Commits
Force Pushes
Genuine and Frequent Commits
No Compilation Errors


The following section gives an outline and some guidance to each of the Git etiquette rules and best practices





Meaningful Commit Messages

When creating a commit message (git commit -m "This is a commit message"), ensure that the message is informative and relevant to the changes that the commit encompasses.

Writing good commit messages is an extremely beneficial skill. Indeed, commit messages are a means to communicate your code changes to your team. Also, commits are an archive of changes (you can read the history of the project with git log). They can become an ancient manuscript to help you and future team members decipher the past, and make reasoned decisions in the future.

More Information:





Commit Message Length

We will report a Git violation if your commit messages have less than five words. This is an arbitrary word count for a commit message. However, it is helpful as it ensures you are providing value to your peers by creating informative and nontrivial commit content. We discourage short messages when committing as others see your commits will not have enough information to understand the content of the commit.

Edit SOFTENG 281 Marking!

Commit messages should have at least five words.





No Empty Commits

Avoid empty commits Git allows to make an empty commit (with the flag –allow-empty). A commit that does not add new or modified code to the repository and serves little purpose in the Git history. For the purpose of your assignments, using empty commits is considered to be forging your Git development history and should be avoided.

Edit SOFTENG 281 Marking!

You should not have empty commits.





Force Pushes

Force pushes are heavily discouraged as you risk losing commits as the branch history is overwritten. Instead of force pushing, consider using git-revert to revert the commits that have been made to the branch by creating a new commit. In this way, there is no risk of losing any commits that were made on a branch.

More Information:

Edit SOFTENG 281 Marking!

You should never use the flag --force or -f when doing a git push





Genuine and Frequent Commits

Commits should be genuine and frequent. This means that you should not commit all your work at once, but rather commit (and push) frequently as you make progress. This is important for many reasons:

  • It backs up your work in case something happens to your computer.
  • It allows you to keep track of your progress and revert to a previous (working) state if you make a massive mistake.
  • It ensures academic integrity by providing a clear record of your journey to the final solution. This makes it clear that you did the work yourself and didn’t copy from someone else.
  • Marks are allocated for the number of (genuine) commits you make. If you make very few (genuine) commits, you will get a low mark for this criterion. If you make frequent and many (genuine) commits, you will get full marks this criterion.


“What is a “genuine” commit?”

We have developed automated tools that allow us to detect whether a commit is genuine or not. This is to avoid students making “fake” commits to get marks. There are many dimensions that go into deciding whether a commit is genuine or not, and it’s often a combination of many factors that determine whether a commit is genuine or not:

  • The consistency of edits from the start to end of the assignment. Were many of the commits “tiny edits” aimed to inflate the number of commits, with some “big” commits (“dumps”) in between? Or were the commits consistent in size and nature?
  • Between the commits, were you generally making more progress in terms of passing more test cases and/or improving the quality of your code? Or were you making little progress, and then suddenly making a lot of progress in one commit?
  • Do the edits in the commits resemble a likely workflow, of adding new code, fixing bugs, and refactoring? Or do the commits look like they were made by copying and pasting code sections across?
  • Is the code compiling and passing tests in the commits? Or are the commits broken? Broken commits are a sign of “text dumps” without understanding the implication of those edits (i.e., adding that code without testing it, often resulting in code not compiling as it’s not coherent).
  • And plenty of other signs.


“What is a “frequent” commit?”

Commits are considered “frequent” if they resemble incremental progress. This means that you are making progress in your assignment, and committing your progress as you go. This is in contrast to “text dumps”, where you make a lot of progress, and then commit all of it at once.

You should really be aiming to commit once for every test case you pass. This is a good rule of thumb. If you pass a test case, commit. If you pass another test case, commit again. If you pass another test case, commit again. And so on.

This is not just about getting marks. This is about good software development practice, and also demonstrating academic integrity. This also protects you if you made major changes to your code, and then you realise you made a mistake. If you committed frequently, you can easily revert to a previous commit. If you committed infrequently, you will have to undo a lot of work, and you might lose a lot of your work in the process.


The bottom line is: if you are making genuine progress, and committing frequently, you will be fine.

It’s all about being transparent about your progress and your journey.

Edit


Good Examples

Here are some examples of what we consider to be “genuine” and “frequent” commits:

Edit

Edit


Bad Examples

Here are some examples of what we consider to be commits that do not appear to be not “genuine” and/or “frequent”:

Edit

Edit

Edit


Marking Git Etiqutte

You should first be guided by the rationale discussed above regarding Git etiquette, in that your priority should be to demonstrate genuine progress and frequent commits.

When it comes to “quantifying” Git etiquette, we have to make a call on how to translate it into a mark. This is not an exact science, and it’s not always clear-cut. However, we have developed a system that we believe is fair and reasonable.

Below we speal fairly generically, as the exact numbers might change from assignment to assignment. However, the principles remain the same.

Let’s assume we have an assignment where we are marking Git etiquette out of 2%. Here is how we might mark it. If we look at the table outlined at the top, we need to recognise that some of the issues (such as empty commits and force pushes) are more severe than others. You won’t be “rewarded” for not making empty commits or force pushes, but you will be penalised if you do make them. These penalies are direct and severe, as they require a deliberate action on your part to make them. Especially for force pushes, there is no excuse for this and it is considered tampering with the commit history.

Other issues, such as commit message length, isn’t so severe. We therefore provide some leniency here. How much leniency depends on which assignment (the latter assignments we’d expect you to be more proficient in Git usage). How many times you can make this violation we will base on the number of commits you made. We will have a threshold for the number of violations you can make before you start losing marks. For example, we might excuse 5% of your commits as a violation (we are just saying too few words here). The mark is then the proportion of remaining violations based on the remaining number of commits. This way, if you made plenty of commits and few violations, you will hardly feel the hit for this. If you made a few commits, then those violations would end up being a larger proportion of your mark. Of the (example) 2% for Git etiquette, we might allocate (for example) 0.5% for commit message length. However, you need to make sure you are not trying to “hide” a violation by making a lot of unncessary commits. We will be able to detect this, and those inflated number of commits might incur a penalty. It’s all about being transparent and genuine about your progress and your journey.

When compilation errors are penalised, this is considered a medium severity issue. It’s not as severe as empty commits or force pushes, but it’s still a serious issue. This will again be a direct penalty for each broken commit, but we might have a threshold for the number of broken commits you can make before you start losing marks. Again, this will be based on the assignment. Please don’t ask “how many broken commits am I allowed?”, as we don’t know until we have done the marking. Besides, it’s not a target you should be aiming for. You should be aiming to have no broken commits at all.

Finally, we look at genuine and frequent commits. This is the most important part of Git etiquette. If you are making genuine progress and committing frequently, you will be fine.

Finally, the “2%” is scaled based on the number of commits you made. As a rule of thumb, we will usually expect you to have as many commits as there are test cases. Because, in addition to the test cases, there are also code-style commits to be made. Again, this isn’t a number you should be asking “how many commits should I make?”. You should be aiming to make as many commits as you can, and you should be aiming to make genuine progress and commit frequently. If we tell you up front it’s “10”, then most students will aim for “10” and no more. This is not the right attitude to have. You should be aiming to make as many commits as you can, and you should be aiming to make genuine progress and commit frequently. It’s all about being transparent to demonstrate your progress and your journey.

Let’s say we expected 25 for a particular assignment. If you made less than 25 commits, you immediately start to lose a proportion of the 2% mark based on how many commits you made (divided by 25). So if you made only 10 commits, the most you can expect is 10/25 * 2%.

So let’s say the remaining portion is for the genuine and frequent commits. This is the most important part of Git etiquette. If you are making genuine progress and committing frequently, you will be fine. This is based on the “biggest jump” in your progress graphs. We only consider jumps in the given test cases (since you don’t know what the hidden ones were). We will usually use 5 as the maximum allowed “jump” in progress. If you had at most 5 (or less) “jump” in the number of test cases passed (based on your previous set of commits), you would get the full (example) 1.5%. Otherwise, you will see (example) 0.2% penalty for each increment over the “jump threshold” for your jumps over the 5 threshold. So if you had a jump of 10 test cases, you only get 0.5 out of the 1.5 ((10-5)*0.2).

Let’s assume here is the order of (given) test cases you pass, where X means a compilation error:

0, 2, 6, 4, 8, 8, 1, 9, X, 10, X, 13

The “jumps” are determined relative to the previously-maximum score you got. It’s not relative to the immediate-previous commit.

In the example above, the “jumps” are:

  • 2 (from 0 to 2) — 2 becomes the “biggest jump so far”
  • 4 (from 2 to 6) — 6 becomes the “biggest jump so far”
  • 0 (from 6 to 4)
  • 2 (from 6 to 8) — 8 becomes the “biggest jump so far”
  • 0 (from 8 to 8)
  • 0 (from 8 to 1)
  • 1 (from 8 to 9) — 9 becomes the “biggest jump so far”
  • 0 (from 9 to X)
  • 1 (from 9 to 10) — 10 becomes the “biggest jump so far”
  • 0 (from 10 to X)
  • 3 (from 10 to 13)

All jumps were below 5, hence no penalty (despite there being jumps greater than 5 for adjacent commits — but that’s not how we mark it, we look at overall upwards trend).




No Compilation Errors

Your code should compile at each commit, not only the final commit. If your code does not compile at any commit, it is considered to be a “broken” commit.

This might happen for a variety of reasons, such as:

  • You made a syntax error in your code.
  • You forgot to add a file to the commit. Remember, if you add a *.java source file to your project (as you should be for new classes), you need to add it to the commit as well. You can do this with git add <filename>. Always check with git status to see what files are staged for commit, and that there aren’t any source files that are untracked.
  • You might be “text dumping” code without understanding the implication of those edits.
  • You might be committing code that you haven’t tested yet.
  • You might be committing code that you know is broken, but you’re hoping to fix it later.
  • You might be committing code that you know is broken, but you’re hoping we won’t notice.
  • And plenty of other reasons.

How do you avoid this?

  • Test your code. Before you commit, make sure your code compiles. If you’re adding new code, make sure it compiles and runs as expected. If you’re changing existing code, make sure it still compiles and runs as expected.

  • Check git status. Before you commit, check git status to see what files are staged for commit. Make sure you’re not missing any files that should be committed. In particular, pay attention to the Untracked files section as that means the file(s) are not staged for commit and completely ignored at that point.

  • Commit frequently. If you commit frequently, you will be able to catch compilation errors early. If you commit infrequently, you might have to go back a long way to find the error, and you might lose a lot of work in the process.

As you can see, this is not just about getting marks. This is about good software development practice.


In the example below, the developer was doing reasonably well at the start of the assignment, despite having a couple of broken commits. However, towards the end of the assignment, they started making only broken commits. This is one of the extreme cases, but it’s a good example of what not to do:

Edit

Refer to the Good Examples section above. See how there are no broken commits in those examples for the entire assignment.


“I have a broken commit. What do I do? Will I lose marks?”

Don’t worry! If you have a broken commit or two, it’s not the end of the world. We understand that mistakes happen.

However, if you have a lot of broken commits, it’s a sign that you’re not following good software development practice, or you’re not understanding the implications of your edits, or you’re not double-checking you staged all the files you need to commit, or you’re not testing your code before you commit, or you’re hoping we won’t notice.

Don’t try and “fix” the broken commit. Just leave it there. It’s a good reminder to you that you made a mistake, and you should learn from it. You also aren’t allowed to “fix” broken commits, as that would be tampering with your commit history and the consequences of that are more severe (e.g., potentially losing marks for the entire assignment).

We cannot answer the following questions:

  • “How many broken commits are too many?”
  • “How many marks will I lose for broken commit(s)?”
  • and so on.

It’s a case-by-case basis, and we will make a judgement based on the severity of the broken commits, overall quality of the commits, and other factors. We only know this information at the end of the assignment, so we can’t tell you how many marks you will lose for a broken commit until we have done the marking.