Skip to content

Instantly share code, notes, and snippets.

@ajx42
Last active March 24, 2023 13:09
Show Gist options
  • Save ajx42/2c2144d584bd687d6c8db96dde74b0f3 to your computer and use it in GitHub Desktop.
Save ajx42/2c2144d584bd687d6c8db96dde74b0f3 to your computer and use it in GitHub Desktop.
Project Organization Guidelines for Projects

Project Organisation Recommendations

Git is an incredible tool for managing your software development projects. Combine this with Github/Gitlab and you have a powerful environment to work on large scale projects as a team. Note that this gist is not a tutorial. Instead it is meant to serve as a guide to how to use what Github/Gitlab provide.

Along with Git and co I've also included general recommendations on how to make progress on your software engineering project.

Most of it is just "opinion" based on my software engineering experience. So you should feel free to experiment and figure out what works out the best for you.

At the end of this gist, you will find a handy list of useful Git commands.

The main branch

  1. The main branch should always work at all points in its commit history. Never intentionally merge broken code to it. If the team needs to collaborate on a piece of code that is broken, create a development branch and merge it into main when you are done.
  2. Only merge adequately well-written code to main. "Merge it now and we can clean it up later" is a bad idea.

The key idea here is to maintain production quality code on main from which releases can be made at any time without having to do cleanups or fix anything.

Dev

  1. Since the main branch has to maintain high quality, make it a rule to never directly commit to main. For any new task, one should create a branch off top of main and work on it. This working branch can contain temporary or even broken code.
  2. Once a task is done, a PR should be raised to merge it into main. This PR needs to be reviewed for code quality, performance, and correctness.
  3. Use Squash & Merge option to merge the PR. This should be available in the PR UI. This squashes all commits being merged into main through the PR into a single commit. The commit message can then be neatly written while merging (also through the UI).
  4. Who should review? Generally a few people who regularly work with the specific component. Often, the project owner can take a cursory look to get acquainted with the latest changes.

If you are following these guidelines, you will likely be doing one PR for each task. This means that the PRs will remain small. Squash and Merge option will help maintain a useful and readable (understandable and clean) history of the main branch. Moreover, it also makes it easy to revert certain PRs/tasks entirely by simply reverting the single commit that resulted from Squash and Merge.

Consider this PR for a tool called WowConcert, that I made during one of my course projects.

  • Note that the working branch is called ajain-ab-test and the entire task was accomplished on this branch before review and merge.
  • The branch is reviewed by a teammate who asks questions to understand the code better.
  • Furthermore, while working a lot of commits were made on the working branch. Many commits don't quite have useful commit messages (outside of the context of the task).
  • However, the PR is ultimately squashed and merged to result in a single commit with a very readable message. This single commit contains the entirety of this work.
  • This also maintains guideline #1 that main is never broken since it works both before and after this commit. The same can't be said had we simply merged without squashing since we allow breaking commits on working branches.

Simple example of reviewing PR for code quality.

Merge vs Rebase

  1. Prefer rebase over merge while sync-ing your working branch with the main or any other branch, as far as possible.

At times you may need to merge the changes contained in two branches or simply sync-up your working branch with the latest changes on main.

  • In Git, it may be tempting to simply merge. However, rebase is interestingly simpler to understand.
  • Rebase puts all your new commits on the current branch on top of all commits of the branch you are rebasing on. This makes the commit history easy to understand since commits are not interleaved.
  • Rebasing doesn't generate any automated merge commits and so once again the commit history will look a lot simpler.
  • Rebasing may involve a bit more effort than merge, since your commits will be replayed on top of the branch you are rebasing on top of one by one and you will be required to fix conflicts for each commit if needed.
  • While playing with rebase you may need to at times use --force push. Be very careful using this. This is another reason we have #3 so that we don't accidently force push to main.

Automation/Scripts/Environment

  1. Have a tight code-build-test loop. You should be able to build your code and test your build quickly while developing software. Try not to write thousands of lines of code that isn't (atleast) built (or tested). The more you wait on this, the harder the task gets in getting things to work later on. A tight development loop avoids this and you will find yourself motivated by being able to incrementally build.

  2. Build skeleton first. #8 implies making incremental changes to the software being developed. This means that a basic version of application that is able to run is the first requirement. Try to reach this skeleton as early as possible, then continue to extend it and add features in a tight development loop.

  3. This follows from #8. Automate your build and test process as much as possible. This generally means having some shell or python scripts that let you build your project quickly. As the project grows, these scripts will also grow, they may just get longer or may become more sophisticated allowing more and more settings. It is a good idea to use build systems like maven or cmake.

Sometimes writing scripts that don't directly contribute to your project may not sound like a great idea. But it is an investment. Automating build process or tests will save many development hours later on and will make your life easy. It also helps avoid procrastination when it comes to building and testing.

This leads to a more generic guideline.

  1. Take some time to create a usable dev environment:
  • Set up your IDE / editor with proper and useful plugins.
  • Create keyboard shortcuts for tasks that you usually find yourself clicking around for.
  • Set an aesthetic colour scheme - yes it matters sometimes!
  • Have a shell prompt that contains information you require (eg. your git branchname might be useful information to print in the prompt).

A little bit of investment will save a lot of time later on.

List of useful Git commands

Git has a lot of features and is extremely powerful. However 95% of the times you don't need the entire arsenal at hand. Here is a list of git commands that you may possibly need. Note that you don't even need to know these all, just a small subset of these will help you get through most of the tasks.

0: fetch, push, pull, commit, log, add, diff, checkout, branch, clone
1: rebase, merge, reset
2: cherry-pick, revert, stash, reflog
3: rebase -i, submodules, anything with --force

More?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment