-
-
Notifications
You must be signed in to change notification settings - Fork 561
Working on c:geo for git beginners
This describes the development setup and workflow for c:geo for a git beginner audience. Git experts may choose different settings at one point or another of course, but please also follow the c:geo Standard Development Workflow (see next section).
Note: The following examples in this guide assume that you have a GitHub user called bruno and your local c:geo repository is stored in a folder called d:\dev\cgeo.
The standard workflow for working on c:geo uses a couple of assumptions / prerequisites:
- You have forked the original c:geo repository (e.g. from
cgeo/cgeo
tobruno/cgeo
) - see below in "Initial Setup of environment" section - Every work is done on a local copy of your fork.
- You do not commit changes directly to the c:geo repository, but to your fork.
- And then create a PR in c:geo using GitHub web page.
Some conventions we use:
- Use rebase wherever possible (e.g. always use
pull --rebase
over purepull
). This is to avoid merge commits. - If possible, squash non-meaningful commits before issuing a Pull Request (e.g. commits removing typos or to fix CI issues). This is to avoid overly large and meaningless commit history in
master
branch.
The following tries to guide you through the different steps and name a couple of useful git commands. It assumes you are using a git command line tool, but most steps can be done using some sort of GUI (e.g. Android Studio) as well (see menu VCS → Git
).
git is a version-control system. When installed locally, it manages the content of a root folder with all its files and (sub)folders as a so-called repository. Git is distributed, meaning that each installation manages its own repositories, but those repositories can be synced with each other. Basic concepts are:
- A commit is a set of changes to files (adding, modifying or deleting files) which moves the underlying repository from one version to the next. It can be seen like a transaction to the repository
- A branch is a way to isolate different units of work in one repository from each other. A central branch called
master
contains the most up-to-date integrated state of the software. When you work on an issue, you will usually create a dedicated branch for it, work on it and at a later point merge it back to themaster
. By creating (branch
) and switching (switch
) between branches you can also work in parallel on multiple issues within the same repository. - Repositories and branches are synchronized with each other using commands like
push
,pull
andrebase
. Since git is a distributed VCS this is very important.
GitHub is a free cloud service to host remote git repositories. It is specifically designed to aid distributed software development projects like c:geo. It adds to git a lot of very cool features:
- Git Management GUI: since GitHub is in the cloud, you cannot use command line arguments like your local repositories. Thus a GUI is provided
- User Management: GitHub adds the possibility to manage users for repositories, assigning roles and give permissions (e.g. to merge) only to specific people.
- Pull Requests: instead of directly merging stuff into repositories, using PR a user can request that a change is merged. Around the PR concept, things like permission control, automated code checks and peer code reviews are taking place
- Lots of other project development tools like issue tracker or a project wiki are provided as well
You have to do this one time only to set up your development environment. You will set up an environment consisting of three git repositories:
- c:geo main repository (https://github.com/cgeo/cgeo): the main repository for the c:geo project
- Your personal fork/copy of c:geo main repository on GitHub (e.g. bruno/cgeo): this will be used by you to issue pull requests to c:geo main repository
-
A local clone/copy of your personal copy of c:geo on GitHub (e.g. at
d:/dev/cgeo
): this is your local copy to really work on the code
On GitHub:
- create an account at GitHub
- If you want to use
ssh
later instead ofhttps
(optional but recommended): set up or check your ssh settings. See here for details-
Fork the c:geo repository:
- Go to the c:geo project (https://github.com/cgeo/cgeo) and click
Fork
in the upper right. - For details see fork a repo. Just do the fork online!
- Go to the c:geo project (https://github.com/cgeo/cgeo) and click
-
Fork the c:geo repository:
On your local machine:
- make sure
git
is installed. See github set up for details. - open a
git-bash
and navigate to your root development folder (e.g.d:\dev
) - Clone your forked repository:
- If you want to use
ssh
:git clone git@github.com:bruno/cgeo.git
- If you want to use
https
(Update: note thathttps
will be desupported by GitHub in August 2021, so rather usessh
):git clone https://github.com/bruno/cgeo.git
- If you want to use
- (the last step automatically created the standard alias
origin
for this remote repository) - Create alias
upstream
for the c:geo main repository:- If you want to use
ssh
:git remote add upstream git@github.com:cgeo/cgeo.git
- If you want to use
https
:git remote add upstream https://github.com/cgeo/cgeo.git
- If you want to use
Note that https will be desupported in 2021, so consider setting up ssh right from the start.
In case you have to deal with multiple users on github using different ssh configs, check out this link: https://gist.github.com/jexchan/2351996
Optional initial settings:
- For Windows: set Notepad++ as git editor instead of
vim
:git config --global core.editor "'C:/Program Files (x86)/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin"
- For interactive rebase: set other message format (→ esp. includes author!):
git config --global rebase.instructionFormat "(%an <%ae>) %s"
- Sets globally that every pull request is doing a rebase by default:
git config --global pull.rebase true
On start:
- Refresh your local environment (see follow-up section)
- Checkout the branch you want to use as a base for your development. Normally this is the
master
branch.git switch master
- create a branch for your development:
git switch -c <branchname>
- A typical naming convention for
<branchname>
is to useissue_xxxx
withxxxx
being the issue number of the related GitHub issue your are working on. But that's optional, and you're free to use a different naming.
Now start coding on your issues. Whenever you feel you have achieved something worth saving, commit it and save it also to your personal GitHub fork of c:geo
- commit your changes locally
-
git commit -a
- give a comment in the opened file - or
git commit -a -m <commit comment>
- If you want to have more control over what files should be included into your commit, have a look at the
git add <file>
andgit add -i
commands.
-
- upload your development into your fork on GitHub (origin) - the branch will be created there automatically
- For the first push in this branch:
git push -u origin <branchname>
- for the first push in this branch - for following pushes:
git push
- for following pushes in this branch
- For the first push in this branch:
When you feel that your coding comes to a conclusion and you want to request your code being merged into the main repository, then perform a Pull Request:
- Prepare locally
- Refresh your local environment (see follow-up section)
- Make sure your changes are up-to-standard. At least the Unit-tests should run and
Checkstyle
should pass - If you have many commits on the branch you want to merge consider **squashing ** them (see section "Squasing commits / interactive rebase")
- Open a Pull Request
- open https://github.com/cgeo/cgeo
- click "Pull Request"
- left side (base repository): choose cgeo/cgeo, master
- right side (head repository): choose your fork repository,
- fill out form and submit pull request
- Once you submitted a PR, automated code checks will run (code style, server build and running of unit tests). Only if these automated checks are passed, the PR will be reviewed by a c:geo core team member and, if suitable, will be merged to master.
- If you have to change code AFTER the PR was already issued, simply change it in your branch as before and push changes to your fork (origin). PR will then automatically get updates (checks are retriggered).
Do this regularly to stay up-to-date with the server's code.
- Change to the directory your local copy of your fork is in (e.g.
cd d:/dev/cgeo
) - Check if you have local changes not yet committed:
git status
. If you have:- Either: Commit your changes (normally it is sufficient to do a
git commit -a
) and merge again - Or: Stash away your changes (
git stash
) merge again and then re-apply the changes (git stash --apply
)
- Either: Commit your changes (normally it is sufficient to do a
- fetch the most recent changes from the upstream repository to the local copy of your fork:
git fetch upstream
- rebase your local and fork master branch to have the same contents as the upstream master branch:
git switch master
git pull --rebase upstream master
git push origin master
- Rebase your local working branch with the refreshed master:
git switch <branchname>
git rebase master
- Note: this step may result in merge conflicts. See section "Rebasing a branch and handling merge conflicts" if this happens.
- If you're working with
release
branch as well, repeat the last steps for release branch:git switch release
git pull --rebase upstream release
The base of your branch is the branch you have been on when you created your new branch, and with the state it then had. Sometimes it is necessary to update that base, e.g. when you have conflicting changes signalled by GitHub. To resolve this, you need to do a so called "rebase" to your base branch.
- refresh your local environment as described above
- change to the branch you want to rebase:
git switch <issue_xxxx>
- rebase the branch (in this case to
master
):git rebase upstream/master
Sometimes there may be conflicting changes which prevent an automatic merging by git. Look for lines having the word CONFLICT
in the git message.
-
If you have changes which conflict with changes made online,
git rebase
will not succeed. - git will name the the conflicting files, and you will have to resort the conflicts in the editor.
You can resolve the conflicts in different ways:
- Way 1: Using Android Studio
- Open Android Studio, navigate to
VCS → Git → Resolve Conflicts
- You will get a list of all files with merge conflicts. Choose one and select
merge
- In the following three-parted screen (left: your version, right: server version, middle: merged version), use the tools to resolve conflicts
- Click
Merge
to conclude merge. AS will automatically issuegit add
for you in the back
- Open Android Studio, navigate to
- Way 2: use normal text editor:
- Open conflicting file with text editor
- Conflicting parts are marked in the file with
>>>>>
and<<<<<
. - After having resolved the conflicts, you will have to add the files again (using
git add
command), and when all conflicting files are resolved, you can continue the rebase:
Either way, after resolving all conflicts, continue rebase with:
-
git rebase --continue
.
Finally, when everything's ready, you can re-push to the server. As you have changed an existing commit, a regular git push
will fail. You will have to add the --force-with-lease
parameter to overwrite the existing commit:
git push --force-with-lease
When you work on an issue in your branch, you can commit as often as you like and that is totally fine. However, when this branch is merged in the end into the c:geo master, then all these commits will be visible in the c:geo master history for all times. This is usually fine when the number of commits is low and they have meaningful messages/changes in them. However, sometimes it happens that there are many commits with messages like Make CI happy
or save local work to server
, which are relevant for your development but should maybe not end up in public history of c:geo master.
This is where "squashing" might be a good idea. Squashing commits means to merge multiple commits into a single one. This can be done using interactive rebase.
Warning: interactive rebase is a powerful tool, but when used wrong it can result in loss of work. If you use it for the first time, consider make a local backup of your changes sources before.
To squash all commits of one of your branches into one:
- Refresh your local environment
- Change to branch:
git switch <branchname>
- Start interactive rebase:
git rebase -i --keep-base --fork-point master
- → Git will open a text editor LISTING all these commits, with the word
pick
at the beginning of the line - Change the word
pick
tosquash
(ors
) for all lines EXCEPT THE FIRST ONE (leavepick
there) and close the editor - → Git will open another text editor asking you for a new commit message for the new squashed commit
- Enter/change the suggested message and close the editor
- → Git will conclude the squash
- Issue
git log
→ you should only see one commit for<branchname>
- Push this to your origin:
git push --force-with-lease
Some notes:
- Interactive rebase has lots of more options, most of them explained in the text files git opens in the editor
- Interactive rebase rewrites git history. This is only save when used on branches/repositories where you are the single user
This is a more or less unsorted list of useful git commands
- Show differences:
- check what a
git commit
would upload / what did you do since your last commit:git diff
- check what a
git merge upstream/master
would do with the code on your computer:-
git diff ...upstream/master
(taken from http://stackoverflow.com/questions/5817579/how-can-i-preview-a-merge-in-git)
-
- Visual comparison (if you have configured a diff tool like
WinDiff
orBeyond Compare
)git difftool
- check what a
- Working with branches
- List branches:
git branch
- Delete local branch:
git branch -d <branchname>
git branch -D <branchname>
- Delete remote branch:
git push -d origin <branchname>
- Undelete a deleted branch:
-
git switch -c <branchname> <sha>
(<sha>
being the checksum determined bygit reflog
)
-
- Retarget a branch from master to release
-
git rebase --onto release master
Afterwards, you needgit push --force-with-lease
to push the changes
-
- List branches:
- reflog
- pretty formatted reflog:
git reflog --format='%C(auto)%h %<|(20)%gd %C(blue)%cr%C(reset) %C(red)%an%C(reset) %gs (%s)'
- pretty formatted reflog:
To ignore the translation files while merging branches, you need to accept the .gitconfig
configuration with running the following command in you're local cgeo repo: git config --local include.path ../.gitconfig
(See issue #9259)
Information
Development
- Join the team
- Development Environment
- GitHub
- Coding conventions
- design conventions
- Working on c:geo for git beginners
- Creating custom Android icons
- Translation
- Release Preparation
- Continuous Integration
- c:geo notifications
- Logging
Usage
- Creating offline maps
- Send a debug log to the developers
- 'New Map' feature description
- Presenting a demo
Technical documentation
- Heading
- Screen densities
- GPS low power mode
- DB Schema
- Map usages
- Disk Usage Structure
- Trackable parsing
- UnifiedMap
Misc
Outdated: