Skip to content

Development Workflow

Federico N. Pedron edited this page Sep 18, 2019 · 53 revisions

The main repository of LIO (this one) will permanently maintain the two basic branches of the code: master and develop. We have master as the placeholder for the latest official release of the code, whereas develop is where new features are continually incorporated. This repository might eventually also host some release or hotfix branches, but these should be transitory.

If you want to contribute to our code, the first step is creating a github account (sign up here) and forking this repository (click "Fork" on the upper right corner of this page). The following sections contain basic descriptions on the 4 most important processes you will need to perform. Basic knowledge on how to use git is required (such as how to merge or push) and further knowledge on how git and github work is encouraged, but this should cover the basic idea.



Cloning your repository

When you clone your repository, you make a local copy in your computer of all the information on your remote repository. This local copy is "linked" to the repository hosted in github so as to let you easily update changes in one or the other. This way you can not only keep those two synced, but also all your cloned copies in all your workstations.

The process of cloning a repository is described in the main page of this Wiki, and you could adapt that for your forked version and use it as it is. Here we will first describe how to set up a clone by using the ssh protocol instead of the https, because the first one is usually more secure and comfortable for development (to reconfigure a clone from https to ssh, check this link). If you wish to keep using https, feel free to skip this part except for the third step of setting up the upstream remote (adapted for https).

For more information on github protocols, you can check out this link.

  1. You will first need and ssh keypair. You can check your keypairs by running ls -al ~/.ssh: they have the form id_blabla and id_blabla.pub (the private-key and public-key respectively). If you don't have one or you want to create a new one for this clone, you can do so by running:
$ ssh-keygen -t rsa -b 4096 -C "[email protected]"

You can accept the default location, but it is advisable to not leave the passphrase empty.

  1. Then you need to add your private-key to your ssh agent (ssh-add ~/.ssh/id_rsa) and then add your public-key to your github account (you can follow the instructions here). Now you are ready to clone your repository:
$ git clone [email protected]:user_name/repo_name.git local_repo

This will set up a local_repo folder in your current location and download there all the content of your forked repository (user_name and repo_name should be changed with your user and fork's information).

  1. Finally we will set up a special remote that points to the original repository. You won't be able to push here, but I will be useful for pulling data. If you want to know more about remotes you can check out this link. For now, you simply need to run the following command:
$ git remote add upstream [email protected]/MALBECC/lio


Back to the top

Working in Branches

As a general rule of thumb you should never modify master or develop directly. You should always create new branches, make your modifications there, and then merge them back into develop (which will eventually be merged into master).

To create a new branch to work in, you should do so branching off develop by running any of these two set of commands:

$ git branch branch_name develop
$ git checkout branch_name
$ git checkout -b branch_name develop

We include two options for illustrative purposes: the first creates the branch and switches to it in two steps, whereas the second performs both operations with the same command. Now that you have switched to the branch, you have to push it to your remote repository and set it up to track it so that it will know where to push changes. Again, we show how to do so in two steps or in one:

$ git push origin branch_name
$ git branch branch_name --set-upstream-to origin/branch_name
$ git push -u origin branch_name

Your branch branch_name is now ready and configured; to make sure everything looks good, you can run git branch -vv, which should show you your branches and what are they tracking.

Now you can modify files and add your own features, commit to save your changes, and push them to your repository to share among your other workstations or collaborators. Please check out our other sections on how to use commits, style guides and how we organize our code to make sure your contributions will comply with our coding rules. See the last section to find out how to finally incorporate your changes to the official distribution.

A final comment to add is that the name of the local branch and the name of the remote branch is tracking need not be the same name. Moreover, you may have many local branches tracking the same remote branch. This is more advanced git usage and you don't need it by now, but when you are interested you can learn more in our sections on how to manage branches and remotes.


Back to the top

Updating Changes

If new changes by other contributors are incorporated in the develop branch, you will probably want to include them in your working branch as soon as possible. This is because you will have to do it before being able to send your own contributions, and is usually better to incorporate them one at a time that all at once.

In order to do this you will first need to update your copy of the develop branch. This should be an easy two step process in which you first update the branch in your current clone and then push the changes to your online repository. The relevant commands, respectively, are:

$ git checkout develop
$ git pull --ff-only upstream develop
$ git push origin develop

This should run smoothly as long as you keep your forked version of 'develop' as a perfect copy of the one in the main repository. This is why you should always work in separate branches and not in develop directly, and this is why when you ask for a pull request, you do it directly from your working branch (as you will see in the next section).

Now you have to incorporate this new changes in your working branch. The best way to do this that keeps the contribution process as clean as possible is to do a rebase of your work. Basically, git will take the last common ancestor of both branches and then proceed to apply over the last commit of develop all the commits of your working branch that follow said ancestor. To do this you have to run the following command:

$ git checkout branch_name
$ git pull --rebase develop

As with regular merges, you will be asked to resolve any resulting conflicts, but you may be required to do so more that once (remember: all your commits will be re-applied as patches to the last commit of develop). This may seem more obnoxious than a simple merge, but keep in mind that this way the history is kept cleaner and more debug-friendly.

Now when you try to push your updated branch, github will note that the histories no longer coincide. You will need to overwrite the branch in the github repository with your local updated one. Notice how this might be annoying if there are many people working upon this branch. Make sure everybody has commited their contributions before doing the rebase to minimize damage and have everybody collaborate with dealing with conflicts during it.

$ git checkout branch_name
$ git push -f origin branch_name

After having updated both develop and your working branches and pushing to your online forked repository, you will probably want to update your other clones by pulling the new changes. Remember that develop was only fast-forwarded, but your working branches were rebased, so you will have to do force pulls to overwrite your other local configurations.

$ git checkout develop
$ git pull origin develop
$ git checkout branch_name
$ git reset --hard origin/branch_name

Never forget that this rebasing is effectively a re-write of the history of the branch. Overwritting the history of branches (sections) where contributions are decentralized is usually not a very good idea. So be careful when working collaboratively in one of your feature branches and beware of not keeping different commits in different clones for the same branch.


Back to the top

Sending your work

When you are done with a block of changes and you wish us to incorporate it to our official distribution, you need to ask for a pull request. In order to do so, first make sure that you have rebased your branch with the latest modifications in develop and that you have pushed it to your github repository. Please, also make sure you have read and complied with the guidelines uploaded to this wiki regarding code style, organization, testing, etc.

Now go to the online page of your repository and click on the "New pull request" button in the upper left corner, right next to the branch selection list. The base fork should be MALBECC/lio and the base branch should be develop, whereas the head fork should be your own and the head branch your feature branch. Notice that you request a pull directly from your branch in your fork to develop in the original repository without passing through your own copy of develop. As explained earlier, it is important that your forked copy of develop should only be modified by fast-forwarding changes made to the original.

Now that you have sent your changes, all that is left is that someone reviews them and decides whether to incorporate them or ask you to make any modifications. If other incorporations are made before yours is approved, you might be asked to rebase your work again before it can be accepted. As long as the pull request is open, any commit or change you make in your branch will be updated in the request. Please pay attention to the comments and interactions in the pull request. Denials are also a possibility, so to dramatically reduce that chance it helps a lot to check with us before starting to add a feature without us knowing about it. Collaboration is communication.

Keep in mind that if your contribution is accepted, the default way we will incorporate it into the develop branch is via a squash commit. If you wish to keep a more detailed history, please ask so in the request and be willing to discuss it in the comments. It also helps a lot if you have been careful in the way you have kept your commits, amending and squashing to keep a sensible history.

If your branch has been squashed into develop, you will need to overwrite you copy if you want to keep working on it. Instead of rebasing it like you do when other branches are incorporated, you can just perform a hard reset using the following commands (you can use origin instead of upstream if you have already updated your own copy of develop):

$ git checkout branch_name
$ git reset --hard upstream/develop
$ git push -f origin branch_name

After you are completely finished, please do keep in touch in case a problem is later detected in your code modifications (or related to). If you wish to delete your branch you can do so using the following commands: the first one will delete your local branch, whereas the second one will ask github to delete the one in your online repository. Make sure this is what you want before proceeding. You can also archive the branch to keep a cleaner repository.

git branch -d branch_name
git push origin :branch_name


Back to the top

Fixing Bugs

If there is some urgent change that needs to be done to master, a new branch must be created from it.

git checkout master
git merge --no-ff hotfix-v2.0.1

After fixing master, the commit must be cherry-picked to other branches (rc/develop). This MIGHT create a merge conflict between master and develop, but it is cleaner than a constant rebase of develop.