Fork and Branch Git Workflow
This is the definition of the workflow to manage iDempiere commits (starting April 30/2020)
This workflow is usually known as "Forking Workflow" or "Fork-and-Branch Git Workflow" - you can find good explanations about this kind of workflow searching in google.
The document explains how to do it for iDempiere:
Creating a fork
It is encouraged that every developer contributing to iDempiere project creates his/her own fork.
Creating a fork is really easy, just navigate to:
https://github.com/idempiere/idempiere
and push the button "Fork".
This will create a fork in your userspace on GitHub.
Clone locally
To clone locally you can execute on the command line:
git clone git@github.com:(your-github-user)/idempiere.git
NOTE: in case you already cloned idempiere from the official repository, instead of doing a full clone again you can go to your cloned folder and execute:
git remote remove origin git remote add origin git@github.com:(your-github-user)/idempiere.git
Then set the original idempiere as the upstream
git remote add upstream https://github.com/idempiere/idempiere.git git branch --set-upstream-to=origin/master master
You can verify that you have the correct setup with
git remote -v
and you should see similar output to what I've below:
origin git@github.com:hengsin/idempiere.git (fetch) origin git@github.com:hengsin/idempiere.git (push) upstream https://github.com/idempiere/idempiere.git (fetch) upstream https://github.com/idempiere/idempiere.git (push)
And now proceed to configure your development environment as explained in Installing iDempiere
Asking for a pull request
Sync with upstream
You must always ensure that your clone is in sync with the master repository:
git checkout master git pull upstream master # here is usually a good practice to execute # bash RUN_SyncDBDev.sh # to keep your local database in sync with the code git push origin master
Create feature branch
Every commit must be done in a feature branch created for the specific ticket, please never use master or a release branch to commit:
Create a feature branch for the JIRA ticket you're solving:
git checkout -b IDEMPIERE-(Jira-ticket-number)
Develop or integrate a patch
Then you can do the changes or integrate patch being peer-reviewed.
The usual ways to apply patches are:
- normal patch format (f.e. coming from mercurial)
git apply (patch-file)
- patches in git format are normally created using the instruction "git format-patch -1 --stdout (commit) > (patch-file)", these patches can be imported using:
git am --keep-cr (patch-file)
TEST!
You must always ensure you conducted tests before committing, never commit untested code (seriously, your reputation suffers).
Test your changes, and even more important, always check for collaterals of the code you changed, figure out other use cases affected and test them too!
Commit
When all tests are OK add the changed files to stage
git add . git commit
About the commit message:
- use one of your GitHub registered emails
- git note: you can setup your default user and email using
git config --global user.name
andgit config --global user.email
- git note: you can setup your default user and email using
- the commit message MUST contain the IDEMPIERE-(Jira-ticket-number)
JIRA Smart Commits
We have setup JIRA Smart Commits, so you can give some instructions to JIRA in the commit message, for example:
#resolve
-> if your commit resolves completely the JIRA ticket#comment
-> you can add a final comment to the ticket adding #comment (your-final-comment-for-ticket)
TIP about message
You can setup the default commit message to avoid forgetting to add the required information:
echo '# IDEMPIERE-???? [Ticket Description] #resolve #comment [Comment]' > ~/.gitmessage git config --global commit.template ~/.gitmessage
Push
Now push your commit to your own fork:
git push
If it doesn't work try
git push origin IDEMPIERE-(Jira-ticket-number) [your branch]
Pull request
And then navigate in your browser to the URL indicated in the console output, it usually has the form:
https://github.com/globalqss/idempiere/pull/new/IDEMPIERE-(Jira-ticket-number)
To allow easy navigation from the pull request to the JIRA ticket, as the first line of the pull request message we add the link to the JIRA ticket.
NOTE: this is an option that github allows to do automatically just on paid accounts, not provided for the free accounts on open source projects, so, we do it "manually".
Write a proper message there, explaining the impact of the changes, the tests conducted for your use case and other use cases affected.
The more information about the impact and how to test, the easier will be for the peer reviewer to accept the change.
And then submit the request pushing the button "Create pull request".
Changing a pull request
Adding more commits
In case the peer reviewer request changes on the pull request, you can simply do the changes and push the new commits to your repository, github will automatically update the pull request accordingly.
git checkout -b IDEMPIERE-(Jira-ticket-number) # do the changes to code, scripts, etc # git add [files_or_folders] -> to add new files or folders, or change existing files # git rm [files_or_folders] -> to delete files or folders git commit git push
Editing the commit message
The commit message must always contain the JIRA ticket that solves it (and also it can use smart commit message to solve it automatically, in case you're requested to modify the commit message to follow this rules, you can use the next commands to edit the message of the last commit (there is a possibility to edit older commit messages, this instruction is just for the latest):
git checkout -b IDEMPIERE-(Jira-ticket-number) git commit --amend git push --force-with-lease
Approving a pull request
Our workflow is configured to require at least 1 approval from a core developer (different than the requester).
The reviewer can visit the link of the pull request, and follow the instructions there if it is a small commit, a code peer review maybe is enough, if it is a big change, is better to conduct local tests, there are instructions in GitHub about how to test locally the pull request.
In this process, the pull request can be approved, commented requesting changes, or rejected.
After approval
The core developer approving the commit usually pushes the button "Squash and merge" to integrate the code into the official master.
After that you can pull the changes again from the upstream:
git checkout master git pull upstream master
Push the change to your fork:
git push origin master
And delete your temporary feature branch locally:
git branch -d IDEMPIERE-(Jira-ticket-number)
And delete your temporary feature branch on the remote repository (NOTE this is not required if you your repository setting "Automatically delete head branches" is set to true):
git push origin --delete IDEMPIERE-(Jira-ticket-number)
And finally, resolve the JIRA ticket if the development is complete (this step is not required if you used smart commit message as explained above). In this step we usually assign the "Fix Version" to the version running in master.
Tips:
if your local working directory have changes that you need to temporarily put aside, git stash is a very useful tool for that.
Avoid committing to master
To avoid committing by mistake to the master branch you can create the file .git/hooks/pre-commit
with the following content:
#!/bin/sh branch="$(git rev-parse --abbrev-ref HEAD)" if [ "$branch" = "master" ]; then echo "You can't commit directly to master branch" exit 1 fi
And then make the file executable:
chmod +x .git/hooks/pre-commit
Summary
Summarizing, this is how a commit travels between repositories:
- local: push to origin feature branch
- github: pull request to the upstream master
- github: approve
- github: merge to upstream master
- local: pull it back from upstream
- local: push back to your origin master