Version 89 (modified by 5 years ago) ( diff ) | ,
---|
Table of Contents
Git How-to
The repo is here: https://github.com/OSGeo/grass
The instructions for the common cases are in CONTRIBUTING file. Here we discuss more advanced and specific workflows.
If you are long-term GRASS GIS contributor, please note that the development workflow changed significanly after migration from Subversion to Git (GitHub).
Important changes:
- direct committing to "master" (former "trunk") is a no-go and highly discouraged
- hence: you will create a feature branch and open a pull request for a change
- Rationale: pull requests are the perfect platform to discuss/improve changes before merging.
- also applies to core developers (to be discussed)
Workflow
- fork the GRASS GIS repository, and create feature branch(es) with the changes, and suggest your changes as pull requests.
Workflow for GRASS GIS git repositories
The same procedure is recommended also from GRASS Addons repository.
Preparation: cloning the repo
First fork the GRASS GIS repo in the GitHub UI to your_GH_account
. This is the same as what GitHub documentation suggests. See: Fork a repo and Syncing a fork in GitHub help.
Note: add SSH key, see GitHub documentation.
Note: If you get the error message: 'ssh: connect to host github.com port 22: Connection refused' (e.g. because you are behind a firewall that blocks traffic on port 22), you can try to replace git@github.com:
with ssh://git@ssh.github.com:443/
, when you clone or remote add repos.
# "origin" points to your fork repo - IMPORTANT git clone git@github.com:your_GH_account/grass.git # add "upstream" remote cd grass/ git remote add upstream git@github.com:OSGeo/grass.git git remote -v # you should see something like origin git@github.com:your_GH_account/grass.git (fetch) origin git@github.com:your_GH_account/grass.git (push) upstream git@github.com:OSGeo/grass.git (fetch) upstream git@github.com:OSGeo/grass.git (push)
Similarly for GRASS Addons repository:
git clone git@github.com:your_GH_account/grass-addons.git cd grass-addons/ git remote add upstream git@github.com:OSGeo/grass-addons.git
Working with git
Note: this requires the "remotes" to be set as shown above.
# updating from git server: fetch all branches from all remotes git fetch --all ### a) updating MASTER # merge updates into local master git merge upstream/master # at this point we have reached: # (HEAD -> master, upstream/master) ### b) updating releasebranch_7_8 # switch to branch # only once git checkout -b releasebranch_7_8 origin/releasebranch_7_8 # next time, git checkout releasebranch_7_8 # merge updates into local branch git merge upstream/releasebranch_7_8 # at this point we have reached: # (HEAD -> releasebranch_7_8, upstream/releasebranch_7_8) # update own remote # - clears "Your branch is ahead of 'origin/master' by XX commits.", and # - avoids "This branch is XX commits behind OSGeo:master." on GitHub web interface git push origin master # list existing branches git branch -a ##### Implementation of own changes # create new local branch (pick a new name for feature_branch_name) git checkout -b feature_branch_name # <make local source code changes> vim ... # list local changes git status git add file1.c file2.py ... git commit -m 'my change with reasonable explanation...' # push feature branch to origin, i.e. your fork of the OSGeo/grass repo git push origin feature_branch_name # create pull request in GitHub Web interface (the link is then shown in the terminal) # during PR review phase, make more local changes if needed git add . git commit -m 'my second change' git push origin feature_branch_name # ..... will be added to existing pull request
NOTE: for different pull requests, simply create different feature branches.
Keep your local source code up to date
[from https://github.com/OSGeo/gdal/blob/master/CONTRIBUTING.md#working-with-a-feature-branch]
You may need to resynchronize against master if you need some bugfix or new capability that has been added since you created your branch
# assuming that "upstream" points to OSGeo/grass git fetch upstream git rebase upstream/master # if rebase fails with "error: cannot rebase: You have unstaged changes...", then move your uncommitted local changes to "stash" git stash # now you can rebase git rebase upstream/master # apply your local changes on top git stash apply && git stash pop
Continue do your changes and commit/push them (ideally to a feature branch, see above).
Switching between branches
For an elegant way of multi-branches in separate directories with only a single repo clone, see
https://lists.osgeo.org/pipermail/grass-dev/2019-May/092653.html
Testing pull requests from other contributors in master
GitHub provides command line instructions under each pull request ("Pulls" tab). Please check there.
Applying a diff file locally
Downloading a pull request as a diff file (example):
cd path/to/grass_git/ # use the PR number and simply add .diff to the URL wget https://github.com/OSGeo/grass/pull/174.diff
Patching local repo with git
(continuing with example diff):
# first the stats about the patch (see what would be changed) git apply --stat 174.diff # dry run to detect errors (should show no output, i.e. no errors): git apply --check 174.diff # apply patch locally, continue committing as usual git apply 174.diff git status # ... now comment on PR in GitHub, etc. # FYI - here how to undo a local patch: git apply --reverse grass_code_changes.diff
Fixing bugs in a release branch
To directly fix bugs (ideally via feature branch), do
(example: https://github.com/OSGeo/grass/tree/releasebranch_7_8)
# push to release_branch, we assume it to be checked out cd releasebranch_78/ # be sure to locally have all updates from server git fetch --all git branch --merged # create feature branch git checkout -b r78_fix_xxx # ... do changes... git status git add ... git commit -m 'useful commit msg...' # push to feature branch git push upstream r78_fix_xxx
Now create the PR in GitHub UI using the link shown by git push ...
in the terminal.
IMPORTANT: switch there to release_branch_X_Y**
After PR positive review, merge PR in GitHub.
Local cleanup after successful PR merge:
# switch to release branch git checkout releasebranch_7_8 # be sure to locally have all updates git fetch --all git branch --merged # delete local feature branch as no longer needed git branch -D r78_fix_xxx git fetch --all --prune git branch -a
Backporting to release branches
Preparation
If you checked out the release branch into a separate directory, be sure to have "upstream" enabled as a remote:
git remote -v # if upstream is missing, execute git remote add upstream git@github.com:OSGeo/grass.git
Backporting of a single commit from master to release branch
Assumptions:
- Your own fork is defined as "origin".
- The OSGeo repo is defined as "upstream".
- Using releasebranch_7_8 branch in the examples as the branch to backport to.
First, before you do the git cherry-pick, update the local repo and fork to state of upstream with the following four steps.
Get latest changes to your machine:
git fetch --all --prune
Go to the branch:
git checkout releasebranch_7_8
Update the local branch with latest changes from upstream:
git rebase upstream/releasebranch_7_8
Update your the branch in your fork (optional, just to keep things organized):
git push origin releasebranch_7_8
Second, get commit hash from GitHub or git log in master.
Third, cherry-pick the change from master into the branch:
git cherry-pick <hash>
Forth, verify:
git status git log git show
Fifth, push backport to the branch in upstream:
git push upstream releasebranch_7_8
This last steps will fail if somebody else did backport after you did the rebase step above. If that's the case, just update your local branch again with the same git rebase command as before.
Made a mess?
If you made a mess in the upstream repo (the OSGeo repo) or you think you did, consult on grass-dev mailing list.
If you have something you don't like in your local branch or in the branch in your fork, you can trash any changes you made and replace your branch with whatever is in the upstream repo.
Make sure you don't have any local changes or changes on the branch in your fork because this will wipe them out.
Make sure your remotes are set right (see above, origin to your fork and upstream to OSGeo repo):
git remote -v
Make sure you are on the right branch (here using releasebranch_7_8):
git checkout releasebranch_7_8
Bring the local branch to the state of the upstream branch trashing all local changes:
git reset --hard upstream/releasebranch_7_8
Update the local repo from the upstream:
git fetch --all --prune git rebase upstream/releasebranch_7_8
If you want to keep the branch in your fork up to date, you may need to also overwrite anything which is on that branch there. Be sure you are force pushing only to origin and that origin is your fork. Force push the state of the local branch into your fork:
git push --force origin releasebranch_7_8
To confirm that all went well, see whether the commits on your local branch, the corresponding branch in your fork, and the branch in the upstream (OSGeo) repo are the same.
Code review: generate a single diff for a PR with multiple commits
To speed up reviewing of a PR with multiple commits by reading a single diff file, you may diff the branch against the branch origin point. For example, if you PR 28 is on local branch pr_28, branched from master, you can do:
git checkout pr_28 # note: with the three dots, it will only show diffs from changes on your side: git diff master...
For more hints, see e.g. this Stackoverflow discussion.
Merging of Pull Requests
Rationale: We should try to have clean history and good commit messages. This helps really a lot when you try to understand why something is implemented the way it is.
When a Pull Requests (PR) has multiple commits, the merge commit is more or less mandatory because if you don't have it, you can't use git revert
.
PR with single commit
Proposed: when a PR only has a single commit, the "merge commit" doesn't offer anything and it can be avoided by rebasing the feature branch:
Workflow: GitHub > button "Merge pull request" > "Rebase and merge"
Next, you may locally delete the feature branch.
PR with multiple commits
Proposed: it is a good idea to try to squash the accumulated commits in a PR before merging, especially if those are trivial fixes.
As an example, PRxx contains 5 commits. Esp. in case that several commits of them are trivial fixes that only add noise to the history, "squashing" those results in a cleaner history and, among other things, makes it easier to use git bisect
and git blame
.
Importantly, not always commits of each and every PR need to be squashed before merging. When extensive changes are being made, it often makes sense to keep them unsquashed (e.g. to make reviewing easier), but trivial fixes should still be squashed to the main commits.
Citing co-authors in a git commit message
For co-authors, it is suggested using Co-authored-by
at the end of the commit message:
... Co-authored-by: name <name@example.com>
An empty line (i.e., two new lines) is necessary and sufficient (GitHub documentation is little confusing there, but the generally that's what's accepted).
Further reading
- Git Cheatsheet: http://ndpsoftware.com/git-cheatsheet.html#loc=workspace; (click on a field to see the related git commands)
- GDAL contributing: https://github.com/OSGeo/gdal/blob/master/CONTRIBUTING.md
- Splitting a subfolder out into a new repository: https://help.github.com/en/github/using-git/splitting-a-subfolder-out-into-a-new-repository