Git workflow

This guide explains how to update your local copy of pmaports.git, and how to contribute back changes (e.g. after creating a new device port). It is suitable for people who have not used git before.
== The basics ==
=== pmaports dir ===
During pmbootstrap init, the whole pmaports.git repository was cloned to your computer. You can use pmbootstrap config aports to see the path, and if you chose the default work path, you will get:
$ pmbootstrap config aports
~/.local/var/pmbootstrap/cache_git/pmaports
All commands below need to be executed in your pmaports dir.
It's a good idea to make accessing this directory easy with a short command, so consider setting up a shell alias. For bash this can be done by adding alias pma="cd ~/.local/var/pmbootstrap/cache_git/pmaports" to ~/.bashrc.
=== Updating pmaports (rebasing on master) ===
Since we are dealing with a git repository, pmbootstrap leaves the directory alone after the initial clone. It will not automatically update it. The only thing it will do is tell you when your pmaports.git dir is so outdated that you absolutely have to update it, or otherwise it would be incompatible with your pmbootstrap version. But you can always manually update the pmaports.git directory, and it is recommended to do so before you start or continue with making changes to the repository.
==== Make sure that you are on master ====
If you never ran any git commands in this directory before, you will still be on the master branch. Otherwise, run this command to check the branch name (there is also git branch, but we do have a lot of branches, so the one below is probably easier). 
$ git rev-parse --abbrev-ref HEAD
master
Switch back to master if necessary with git switch master.
(You may want to extend your shell to automatically display the branch name when you are inside a git directory, e.g. by using grml-zsh-config and ZSH.)
==== Put your changes into a new branch ====
Check if you made any changes to your pmaports dir. Changes could come from starting a new device port, for example.
When you have made no changes, you can move on to the next step ("Running 'git pull'"):
$ git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
When you have made changes, git status will list the files that were changed:
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
 (use "git add <file>..." to update what will be committed)
 (use "git checkout -- <file>..." to discard changes in working directory)
 modified: device/device-lg-mako/APKBUILD
no changes added to commit (use "git add" and/or "git commit -a")
Create a new branch, commit the changes and go back to the master branch:
$ git checkout -b mynewbranch
M device/device-lg-mako/APKBUILD
Switched to a new branch 'mynewbranch'
$ git add -A
$ git commit -m "describe your change here"
[mynewbranch c9c729a5] describe your change here
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
Note that there are best practices for commit messages, and for commits that actually make it into the master branches of pmaports.git, we try to stick to them. For example: when porting a new device put the codename of your device at the start of the commit message: fairphone-fp2: new device (if the codename is fairphone-fp2).
Type git commit instead of git commit -m "describe your change here" and your editor will show up, where you can type in a pretty commit message. You can change the default editor by changing the EDITOR environment variable.
==== Running 'git pull' ====
Let's fetch the changes from the official postmarketOS repository and apply them to the current branch. Git will even show a nice overview of the files that have been changed, and how many lines have changed.
$ git pull
Updating e8a7926e..8909e932
Fast-forward
 coreapps/coregarage/APKBUILD | 24 ++++++++++++++++++++++++
...
 26 files changed, 307 insertions(+), 181 deletions(-)
 create mode 100644 coreapps/coregarage/APKBUILD
...
If you did not have any local changes, then you are done here.
==== Updating your branch(es) ====
Put all new commits from master into your own branch, and then apply the changes you made on top of that:
$ git checkout mynewbranch
Switched to branch 'mynewbranch'
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: description here
If there are any conflicts, pay attention to the git output and run git diff to see where the conflicts are. Edit the files in a text editor, run git add -A and then continue the rebase.
== Creating a merge request ==
=== Preparation ===
These steps only need to be done the first time.
==== Forking the repository ====
We are currently using GitLab for development. Login to the website, and click here to fork pmaports.git to your own user's namespace.
If you have just registered at GitLab, create a SSH key and store it in the settings.
==== Add your fork as remote ====
Run this, but replace USERNAME twice with your GitLab username.
$ git remote add USERNAME https://gitlab.postmarketos.org/USERNAME/pmaports.git
=== Push changes to your fork ===
The first time you try to push your changes (upload them), git won't know where you want to put them:
$ git push
fatal: The current branch mynewbranch has no upstream branch.
To push the current branch and set the remote as upstream, use
 git push --set-upstream origin mynewbranch
So we will tell git the remote we would like to use.
$ git push --set-upstream USERNAME mynewbranch
Enter passphrase for key '/home/user/.ssh/id_rsa': 
Counting objects: 59, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (39/39), done.
Writing objects: 100% (59/59), 13.48 KiB | 1.68 MiB/s, done.
Total 59 (delta 29), reused 0 (delta 0)
remote: 
remote: To create a merge request for mynewbranch, visit:
remote: https://gitlab.postmarketos.org/USERNAME/pmaports/merge_requests/new?merge_request%5Bsource_branch%5D=mynewbranch
remote: 
To gitlab.postmarketos.org:USERNAME/pmaports.git
 * [new branch] mynewbranch -> mynewbranch
Branch 'mynewbranch' set up to track remote branch 'mynewbranch' from 'USERNAME'.
When you want to push more changes, you can simply use git push for this branch.
There is also git push --force, which can be used to override commits without creating new ones. You can use it after rebasing your branch on master (as explained above).
git rebase -i master is a powerful command to edit previous commits, the -i option stands for interactive. See git-rebase.io for an in depth tutorial on interactive rebasing.
=== Create the MR ===
Simply click the link shown in the git output above, to create the new merge request. Pay attention to the text shown there, following it closely will make sure that your merge request gets merged to master as fast as possible.
=== Check and fix CI / linting issues ===
Your submitted code will be built automatically by the continuous integration system to check for errors, style issues, etc.
Check the results of the automatic build by going to https://gitlab.postmarketos.org/USERNAME/pmaports/pipelines (replace USERNAME with your username) and clicking on the (chronologically) last item. After the build has finished, you get a list of passed (green check-marks) and/or failed (red X) checks. Click on the failed checks and follow the recommendations in the output shown to fix your code.
== See also ==
* https://git-rebase.io/ in depth interactive git rebase tutorial (explains fixing previous commits, squashing commits, splitting one commit into several, reordering commits, etc.)
* Wine project has an excellent Git Tutorial
Category:Guide