|
| 1 | +How to setup and use git for IOTstack development. |
| 2 | + |
| 3 | +1. First, create a |
| 4 | + [fork](https://docs.github.com/en/get-started/quickstart/fork-a-repo) of |
| 5 | + SensorsIot/IOTstack on github. And |
| 6 | + [setup](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account) |
| 7 | + your ssh-keys. |
| 8 | +1. Clone your fork and setup your github username and email |
| 9 | + ``` console |
| 10 | + $ git clone [email protected]:<username>/IOTstack.git |
| 11 | + $ cd IOTstack |
| 12 | + $ git config user.name <username> |
| 13 | + $ git config user.email <1234>+<username>@users.noreply.github.com |
| 14 | + ``` |
| 15 | +1. Add up the SensorsIot/IOTstack upstream |
| 16 | + ``` console |
| 17 | + $ git remote add upstream https://github.com/SensorsIot/IOTstack.git |
| 18 | + ``` |
| 19 | +1. Configure for ease of operation |
| 20 | + ``` console |
| 21 | + $ git config fetch.prune true |
| 22 | + $ git config remote.pushDefault origin |
| 23 | + $ git config --add remote.origin.fetch "^refs/heads/gh-pages" |
| 24 | + $ git config --add remote.upstream.fetch "^refs/heads/gh-pages" |
| 25 | + $ git config branch.master.mergeoptions "--no-ff" |
| 26 | + $ git config fetch.parallel 0 |
| 27 | + $ git fetch --all |
| 28 | + ``` |
| 29 | + |
| 30 | +## Make a pull-request |
| 31 | + |
| 32 | +``` mermaid |
| 33 | +flowchart LR |
| 34 | + upstream["upstream (SensorsIOT)"] -- "1. git fetch + git checkout -b" |
| 35 | + --> local[local branch] |
| 36 | + local -- "2. git commit" --> local |
| 37 | + local -- "3. git push" --> origin["origin (your fork)"] |
| 38 | + origin -- "3. create github pull-request" --> upstream |
| 39 | +``` |
| 40 | + |
| 41 | +Please see [Contributing](index.md) for instructions on how to write commit |
| 42 | +messages. |
| 43 | + |
| 44 | +``` console |
| 45 | +$ git fetch upstream |
| 46 | +$ git checkout -b <your-descriptive-branch-name> upstream/master |
| 47 | +...coding and testing... |
| 48 | +$ git add <your new or changed file> |
| 49 | +Check everything has been added: |
| 50 | +$ git status |
| 51 | +$ git commit |
| 52 | +$ git push |
| 53 | +``` |
| 54 | +When you execute git push, its output should have a link for creating the |
| 55 | +pull-request to github. |
| 56 | + |
| 57 | +## Common operations |
| 58 | + |
| 59 | +### Show compact history with "git lg" |
| 60 | + |
| 61 | +``` console |
| 62 | +$ git config alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit" |
| 63 | +``` |
| 64 | + |
| 65 | +### Remove branches of merged pull-requests. |
| 66 | + |
| 67 | +When your pull-requests have been merged, their branches aren't needed anymore. |
| 68 | +Remove them to reduce clutter and distractions. The master branch is never |
| 69 | +deleted. |
| 70 | + |
| 71 | +``` console |
| 72 | +$ git fetch --all |
| 73 | +$ git checkout master |
| 74 | +$ git branch -r --merged upstream/master | \ |
| 75 | + grep -v origin/master$ | grep origin | sed 's/origin\///' | \ |
| 76 | + xargs -I 'B' git push --delete origin B |
| 77 | +$ git branch --merged upstream/master | grep -v " master$" | \ |
| 78 | + xargs -I'B' git branch -d B |
| 79 | +``` |
| 80 | + |
| 81 | +## Advanced topics |
| 82 | + |
| 83 | +### Fetch all pull-requests as branches |
| 84 | + |
| 85 | +This is handy for easily testing out other persons' suggested changes. The |
| 86 | +branches are of course fetch-only, and you can't push your own commits to them. |
| 87 | + |
| 88 | +``` console |
| 89 | +$ git config --add remote.upstream.fetch +refs/pull/*/head:refs/remotes/upstream/pr-* |
| 90 | +$ git fetch upstream |
| 91 | +``` |
| 92 | + |
| 93 | +*Note:* Everything below requires this. |
| 94 | + |
| 95 | +### Show up-to-date branches not merged |
| 96 | + |
| 97 | +Branches that include the latest upstream/master, but are not merged to |
| 98 | +your current branch, are potentially mergeable pull-requests. This is useful |
| 99 | +for identifying which pull-requests you should be able to merge without |
| 100 | +conflict. |
| 101 | + |
| 102 | +``` console |
| 103 | +$ git fetch upstream |
| 104 | +$ git branch -r --contains upstream/master --no-merged upstream/master |
| 105 | +``` |
| 106 | + |
| 107 | +### Check pull-requests on Github can be merged without conflicts |
| 108 | + |
| 109 | +In git, the only way to know if a branch can be merged without a conflict, is |
| 110 | +by actually doing the merge. An alias to (re-)create a branch named |
| 111 | +`merge-test` and do merges into it: |
| 112 | + |
| 113 | +``` console |
| 114 | +$ git config alias.test-pull-request-merge $'!f() { : git merge && \ |
| 115 | + OPENPULLS=$(curl -s \'https://api.github.com/repos/SensorsIot/IOTstack/pulls?base=master&per_page=100\' | \ |
| 116 | + grep "^.....number" | sed -E \'s/.* ([0-9]+),/ upstream\\/pr-\\1/\') && \ |
| 117 | + git fetch upstream && git checkout -B merge-test upstream/master && \ |
| 118 | + git branch -r --contains upstream/master --no-merged upstream/master | \ |
| 119 | + grep upstream/pr- | sort - <(echo "$OPENPULLS") | \ |
| 120 | + { uniq -d; [[ "$1" ]] && echo "$1"; } | \ |
| 121 | + xargs -I B sh -c "echo Merging B && \ |
| 122 | + git merge --no-rerere-autoupdate --no-ff --quiet B || \ |
| 123 | + { echo ***FAILED TO MERGE B && exit 255; };" ;}; f' |
| 124 | +``` |
| 125 | + |
| 126 | +<!-- Old version using 'plain' commands |
| 127 | +``` console |
| 128 | +$ OPENPULLS=$(curl -s 'https://api.github.com/repos/SensorsIot/IOTstack/pulls?state=open&per_page=100' | \ |
| 129 | + grep "^.....number" | sed -E 's/.* ([0-9]+),/ upstream\/pr-\1/') |
| 130 | +$ git fetch upstream && git checkout -B merge-test upstream/master && \ |
| 131 | + git branch -r --contains upstream/master --no-merged upstream/master | \ |
| 132 | + grep upstream/pr- | sort - <(echo "$OPENPULLS") | uniq -d | \ |
| 133 | + xargs -I B sh -c "echo Merging B && \ |
| 134 | + git merge --no-rerere-autoupdate --no-ff --quiet B || \ |
| 135 | + ( echo ***FAILED TO MERGE B && exit 255 )" |
| 136 | +``` |
| 137 | +--> |
| 138 | + |
| 139 | + |
| 140 | +Then use this alias combined with `git checkout -`, returning your working copy |
| 141 | +back to the original branch if all merges succeeded: |
| 142 | + |
| 143 | +``` console |
| 144 | +$ git test-pull-request-merge && git checkout - |
| 145 | +``` |
| 146 | + |
| 147 | +This merges all branches that are: a) currently open pull requests and b) |
| 148 | +up-to-date, i.e. contains upstream/master and c) not merged already and d) the |
| 149 | +optional provided argument. Note: won't ignore draft pull-requests. If it |
| 150 | +encounters a failure, it stops immediately to let you inspect the conflict. |
| 151 | + |
| 152 | +!!! help "Failed merge?" |
| 153 | + |
| 154 | + *If* there was a merge-conflict, inspect it e.g. using `git diff`, but |
| 155 | + don't do any real work or conflict resolution in the merge-test branch. |
| 156 | + When you have understood the merge-conflict and want to leave the |
| 157 | + merge-test branch, abort the failed merge and switch to your actual branch: |
| 158 | + |
| 159 | + ``` console |
| 160 | + $ git diff |
| 161 | + $ git merge --abort |
| 162 | + $ git checkout <your-PR-branch-that-resulted-in-the-conflict> |
| 163 | + ``` |
| 164 | + |
| 165 | +### Check your branch doesn't conflict with any existing pull-request |
| 166 | + |
| 167 | +When you intend to submit a pull-request you might want to check that it won't |
| 168 | +conflict with any of the existing pull-requests. |
| 169 | + |
| 170 | +1. Commit all your changes into your pull request branch. |
| 171 | +2. Use the alias from the previous "Test all current pull-requests..."-topic |
| 172 | + to test merging your branch in addition to all current pull request: |
| 173 | + |
| 174 | + ``` console |
| 175 | + $ git test-pull-request-merge <your-pull-request-branch> && git checkout - |
| 176 | + ``` |
| 177 | + |
| 178 | + If there is a merge-conflict, see "Failed merge?" above. |
0 commit comments