How to contribute to an existing plugin or library
Template:Development== Introduction == Sometimes you may want to contribute to an already existing ImageJ plugin or library. For example, a bug is found in one plugin and you want to fix it, or you would like to improve one library by adding more functions. This tutorial describes step by step how to do it with a practical case.
In many cases, the plugin or library will have its own source code repository online somewhere. For instance, in the Fiji project, plugin code lives in the Fiji GitHub organization; e.g., the VIB-lib library's repository is VIB-lib. This structure allows for easy, independent development of each individual component.
In this example, we want to fix some bugs and add some functionality to the VIB-lib library. Let's see step by step how to do it:
In your favorite browser, log into your GitHub account. If you don't have an account yet, go ahead and create one.
Go to the library's repository (in this case https://github.com/fiji/VIB-lib) and "fork" the repository (click on the upper-right "Fork" button):
By doing this, you will be duplicating the whole repository into your own GitHub account. This way you can freely work on the library with an identical version of the existing repository's master branch.
Next, go to your command line, move to your workspace folder and clone the repository:
$ git clone https://github.com/username/VIB-lib
(change "username" for your GitHub account name)
To sync changes you make in a fork with the original repository, you must configure a remote that points to the upstream repository in Git. In our case:
$ cd VIB-lib $ git remote add upstream https://github.com/fiji/VIB-lib $ git fetch upstream
Create a topic branch
Create a new branch with a descriptive name. Since we want to work on AmiraMesh files, we call it "amira-io":
$ git checkout -b amira-io
Now we develop our code to include our changes in the library.
The most popular IDE is undoubtedly Eclipse, and you can follow this tutorial to build the plugin or library (you only need to change the URL from the ImageJ repository to the appropriate plugin or library repository URL).
Commit early, commit often!
- Make changes and commit them to your topic branch
- Push the commits to your GitHub repository; e.g.:
git push -u origin amira-io
Finally, once you have tested your new code and are satisfied with the results, you have to propose to add your contributions to the original project. In GitHub, you do so by using pull requests:
First, switch to your branch:
Then click on the Compare & Review button:
After starting the review, you're presented with a review page where you can get a high-level overview of what exactly has changed between your branch and the repository's master branch. You can review all comments made on commits, identify which files changed, and get a list of contributors to your branch.
Finally, when you're ready to submit your pull request, click Create pull request:
Pull request discussion
Once the pull request is created, it is automatically sent to the person in charge of the original repository. After reviewing the basic description, commits, and cumulative diff, the person tasked with applying the changes may have questions or comments. The discussion view is designed to encourage and capture this type of discussion:
Modifying your commits
From the discussion, you might realize you need to modify a part of the changes you made on your branch. Some of the changes introduced by your commits can be fixed with new commits (that will appear in the discussion view of the pull request). But some commits may need to be modified so the history of your repository stays reasonably clean. In that case, you need to use the git rebase command:
You can rebase since a specific commit, for example:
$ git rebase -i 6272a7bf
or since the starting point of your branch:
$ git rebase -i origin/master
In our example, we run the first command and immediately Git launches our default text editor and open a file that details the commits in the range we've chosen:
pick 36fc3d2 Use java.util.zip tools to decode (inflate) AmiraMesh files instead of zjlib methods. pick 25b44e1 Encode (deflate) using java.util.zip methods instead of the zjlib ones. pick 913d6e3 Remove unused imports. pick 45adf88 Add progress bar updates. pick 1d6e8d9 Make call to static method correctly. pick 1c1f88f Correct typos pick 478c271 Fix bug when reading AmiraMesh files. pick ffeaab8 Allow Avizo files to be read as well. pick a3e4aec Remove jzlib dependency, now unnecessary. pick 7d18362 Allow Avizo files to be read as well. pick e768fd1 Add method to write AmiraMesh file faster using more memory. pick 88dbc1c Add method to read AmiraMesh file fast using a more memory. pick 4e4c7a4 Make sure the files and output streams are closed after writing. pick 86a79cf Make the output stream a class field so it can be properly closed as well after writing the file. pick def586d Correct indention. pick c536d3d Make sure the file and input stream are closed after reading. # Rebase 6272a7b..054d243 onto 6272a7b # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out
Breaking this information, from top to bottom, we see that:
- Sixteen commits are listed, which indicates that there were sixteen changes between our starting point and our current branch state.
- The commits you chose to rebase are sorted in the order of the oldest changes (at the top) to the newest changes (at the bottom).
- Each line lists a command (by default, pick), the commit SHA, and the commit message. The entire git rebase procedure centers around your manipulation of these three columns. The changes you make are rebased onto your repository.
- After the commits, Git tells you the range of commits we're working with (6272a7b..054d243).
- Finally, Git gives some help by telling you the commands that are available to you when rebasing commits.
We can now change the first word of any of the sixteen lines to apply any of the six available rebasing commands: pick, reword, edit, squash, fixup and exec. You can also remove any of the lines (so that commit will be lost) or reorder to change the order of the commits.
Once we're done editing this file, we save it and close it. Then Git will go throw our instructions to apply the changes and allow us editing whenever it finds edition commands. In that case, we will introduce our changes in the code and commit them as usual. After that, to continue rebasing we need to call the command:
$ git rebase --continue
If we make a mistake, we can always abort the whole process using
$ git rebase --abort
When we are done rebasing, we should see the following message in the command line:
$ Successfully rebased and updated refs/heads/master.
Finally we should just push the changes into our branch:
$ git push origin +HEAD
Closing pull request
Once all the developers involved in the conversation are satisfied with the state of the branch, the person in charge of the repository will merge and close the pull the request:
This tutorial has been written using the following references: