-
Notifications
You must be signed in to change notification settings - Fork 276
Contribution Workflow
This guide will help you use version control and provide some important commands for contributing to MRover's software. It is NOT intended to be a comprehensive git tutorial. If you have not used git before, you are strongly encouraged to go through a tutorial of some kind to get a functional understanding of what git does (I recommend this one, it provides visuals to demystify what's happening behind all the obscure commands).
Assumptions
- You have completed the Development Enironment Setup.
- You have a basic working knowledge of git.
- Create a New Branch
- Commit Your Changes
- Update Your Branch
- Squash Commits
- Create a Pull Request
- Tips for Success
Before making any code changes, you need to create a branch to work on. If you don't already have your local master branch checked out (you can check this with git status
), do so with
git checkout master
.
If you have not done so, add the main repository as a remote with the name upstream
:
$ git remote add upstream https://github.com/umrover/mrover-workspace.git`
To update your current master branch, pull from upstream
. To maintain a linear change history, MRover uses rebasing instead of merging to combine two branches. So, always use the --rebase
option when pulling:
$ git pull --rebase upstream master
Note that this is equivalent to a fetch and rebase, and you could use these two commands instead:
$ git fetch upstream master
$ git rebase upstream/master
Then use git checkout -b <new branch name>
to create the new branch. To bring this branch to your online fork of mrover-workspace, use git push -u origin <new branch name>
This will allow you to push changes from this local new branch to your online fork, where eventually pull requests can be made.
Once you're ready to contribute your changes to the main repository, you'll need to commit them. First, test your changes! Ensure that your code builds with Jarvis and the changes you've made work. Once you've done that, you're ready to commit them:
$ git status # display status of changed files
$ git add <file1> ... <fileN> # add changed files to be committed
$ git commit -m "<commit message>"
Preface your commit message with a tag that indicates the portion of the repository that this commit is relevant to. For example, if you are going to commit changes to the Ansible configurations, your commit message should begin with the tag "[ansible] ..."
. If you're committing changes to the mobility code, you might use the tag "[odrive] ..."
.
While you were developing, its likely that changes were merged from other developers into upstream
. Thus, the history of your local branch and upstream/master
may have diverged. Before pushing your changes to your fork, you should update your local branch's history to match that of upstream/master
.
Updating your local branch uses the same commands as before:
$ git pull --rebase upstream master
or
$ git fetch upstream master
$ git rebase upstream/master
If you have modified files that were modified in upstream/master
since the histories diverged, you may encounter conflicts during the rebase. If so, open those files, resolve the conflicts in a text editor, then add them and continue the rebase:
$ git add <file with resolved conflict>
$ git rebase --continue
After completing the rebase, your local branch's history should match that of upstream/master
, with your local changes on top as the most recent commits. You can check your branch's history with git log
.
Often while developing, you will naturally break implementation of a single feature into multiple commits across working sessions. Additionally, you may make numerous "garbage commits" for things like small changes, syntax fixes, and comments. You'll likely end up with a history of numerous commits that, taken together, constitute a single feature addition or bug fix. We don't want all those auxiliary commits to clutter the repository's history, so we can use an interactive rebase to squash them into a single, concise commit.
First, initiate an interactive rebase, where NUM_COMMITS
is the number of commits you want to combine into one:
$ git rebase -i HEAD~<NUM_COMMITS>
In the text editor that opens, replace pick
with squash
on all but the top commit. Afterward, save and exit the text editor.
Another text editor will open with the commit messages from each of the commits to be squashed. Change the first commit to the final commit message that describes the changes you made. Finally, save and exit the text editor. If you check your branch's history with git log
, you should see that it is just one commit ahead of upstream/master
.
Now, you're ready to push your changes to your fork. You likely changed your branch's history when you pulled from upstream
, so if you try to push normally git will complain. To get around this, use the -f
option:
$ git push -f
Note: This assumes your local branch is already tracking a remote branch on your fork. To specify the branch to push to, you can use
$ git push -f <remote> <branch>
To request that your changes be merged into the main repository, you'll need to open a pull request. To do so, follow these steps:
- Go to the "Pull Requests" page on your fork on GitHub
- Click "New Pull Request"
- Select the branch on your fork that you want to merge into
umrover/master
- Click "Create Pull Request"
- Give your pull request a title and description
- Click "Create Pull Request" again
Your pull request will then be run through Travis Continuous Integration to ensure that everything in the repository still builds after your changes. After an experienced member of the software branch reviews your pull request and your changes are approved, a member of leadership will merge them. Congratulations! You've successfully contributed code to MRover's repository.
There are many common pitfalls that can make getting your changes merged into umrover/master
a nightmare. To avoid them, please read and follow these tips:
-
Keep your branches up-to-date! The branches on your fork and in your local repository will not automatically update to reflect the state of
upstream/master
. Be sure to regularly follow the steps in Update Your Branch and push to your fork's remote branches to ensure you are developing on top of up-to-date code! There's nothing more frustrating than spending all year developing a large new program and then having issues getting it merged because your branch is 100 commits behindupstream/master
. - If you're unsure of what you're doing, ask your subteam lead or the branch lead! People on leadership generally have a lot of experience working with git and following the procedures to contribute software. If you need help going through the process a few times before you're comfortable doing it on your own, don't be afraid to ask for help!
- Do the visual git tutorial! If you've never used git before, this tutorial is a must. Seriously, even if you're okay with git, I highly recommend you do it as a refresher. The website also has a sandbox mode where you can try out some commands and be sure they'll do what you think they'll do. You can memorize the commands in this tutorial, but once you understand what they're actually doing you'll be able to use git to your advantage and get yourself out of some pretty hairy situations.
-
Branch Early, Branch Often! It's common to do all of your development on branches, and keep your
origin/master
branch in a state that reflectsupstream/master
. In fact, this is strongly encouraged. By doing this, you can always easily create new branches based on the most recent code in the main repository. Furthermore, it helps keep changes that aren't related to each other separate. When it comes time to create a pull request, you don't have to worry about which commits in your history should be included for a given feature - only related changes will be on a given branch.
Something not right? Contact the Software Branch lead.