libjxl

FORK: libjxl patches used on blog
git clone https://git.neptards.moe/blog/libjxl.git
Log | Files | Refs | Submodules | README | LICENSE

developing_in_github.md (13787B)


      1 # Developing in GitHub
      2 
      3 This document describes the development steps related to handling the git
      4 repository.
      5 
      6 If you are new to GitHub, there's a nice [quickstart
      7 guide](https://docs.github.com/en/github/getting-started-with-github/quickstart)
      8 on GitHub explaining the basics.
      9 
     10 ## Initial setup
     11 
     12 You need to perform this set up at least once if you haven't use GitHub before.
     13 Read through the quickstart guide [Set up
     14 Git](https://docs.github.com/en/github/getting-started-with-github/set-up-git)
     15 page to get your git up and running. You will need to Fork a repository next.
     16 After that "Life of a Pull Request" describes the common everyday workflows.
     17 
     18 ### Configure your SSH access
     19 
     20 The easiest way to configure access to your Github repository is to use SSH
     21 keys. For that you need an SSH private and public key, ideally a strong one. You
     22 can use different keys for different sites if you want. In this example, we will
     23 create one for using in GitHub only.
     24 
     25 Create the `~/.ssh/id_rsa_github` file executing the following. (Here and
     26 elsewhere, {{X}} are placeholders for your email/username)
     27 
     28 ```bash
     29 ssh-keygen -t rsa -b 4096 -C "{{EMAIL}}" -f ~/.ssh/id_rsa_github
     30 ```
     31 
     32 Go to your [SSH and GPG keys](https://github.com/settings/keys) settings and
     33 paste the contents of your *public key* (the one ending in `.pub`), that would
     34 be the output of this command:
     35 
     36 ```bash
     37 cat ~/.ssh/id_rsa_github.pub
     38 ```
     39 
     40 To use a specific key when SSHing to the github.com domain, you can add this
     41 snippet of config to your .ssh/config file executing the following.
     42 
     43 ```bash
     44 cat >> ~/.ssh/config <<EOF
     45 
     46 Host github.com
     47   Hostname github.com
     48   IdentityFile ~/.ssh/id_rsa_github
     49   IdentitiesOnly yes
     50 EOF
     51 ```
     52 
     53 The `IdentitiesOnly yes` part forces to only use the provided IdentityFile when
     54 talking to GitHub.
     55 
     56 ### Fork your private copy
     57 
     58 The JPEG XL code is located in [this repo](https://github.com/libjxl/libjxl).
     59 
     60 The normal developer workflow in GitHub involves creating your own fork of a
     61 repository and uploading your own changes there. From your own copy you can
     62 request merges *to* the upstream repository directly, there's no need to create
     63 a branch in the upstream repository.
     64 
     65 [Fork the
     66 repository](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo)
     67 in GitHub to create your own copy of the repository in GitHub. You can then
     68 propose to include changes in the main repository via a Pull Request.
     69 
     70 Once you are done you should have your repository at
     71 
     72  https://<!-- not a link -->github.com<!-- not a link -->/*{{USERNAME}}*/libjxl
     73 
     74 where {{USERNAME}} denotes your GitHub username.
     75 
     76 ### Checkout the JPEG XL code from GitHub
     77 
     78 To get the source code on your computer you need to "clone" it. There are two
     79 repositories at play here, the upstream repository (`libjxl/lbjxl`) and your
     80 fork (`{{USERNAME}}/libjxl`). You will be normally fetching new changes from
     81 the upstream repository and push changes to your fork. Getting your changes from
     82 your fork to the upstream repository is done through the Web interface, via Pull
     83 Requests.
     84 
     85 The [Fork a
     86 repo](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo)
     87 goes in great detail, but uses the git remote names `upstream` for the shared
     88 upstream repository and `origin` for your work. This guide proposes an
     89 alternative naming scheme, used in the examples below.
     90 
     91 In this guide `origin` is the upstream shared repository and `myfork` is your
     92 fork. You can use any other name for your fork if you want. Use the following
     93 commands to set things up, replacing `{{USERNAME}}` with your GitHub username:
     94 
     95 ```bash
     96 git clone git https://github.com/libjxl/libjxl --recursive
     97 cd libjxl
     98 git remote set-url --push origin git@github.com:{{USERNAME}}/libjxl.git
     99 git remote add myfork git@github.com:{{USERNAME}}/libjxl.git
    100 git remote -vv
    101 ```
    102 
    103 These commands did three things:
    104 
    105  * Created the repository with `origin` as the upstream remote,
    106  * Changed the "push" URL to point to your fork, and
    107  * Create a new remote pointing to your fork.
    108 
    109 The last step is optional. Since the "fetch" URL of `origin` points to the
    110 shared repository and the "push" URL points to your fork, fetching from `origin`
    111 always gets the latest changes from the upstream repository regardless of the
    112 contents of your fork.
    113 
    114 Having a second origin called `myfork` is only useful if you need to download
    115 pending changes from your fork from a different computer. For example, if you
    116 work on multiple computers, each one with this setup, you can push to your
    117 fork from one, and then fetch from `myfork` from another computer to get those.
    118 
    119 # Life of a Pull Request
    120 
    121 The general [GitHub flow
    122 guide](https://docs.github.com/en/github/getting-started-with-github/github-flow)
    123 applies to sending Pull Requests to this project.
    124 
    125 All the commands here assume you are in a git checkout as setup here.
    126 
    127 ### Sync to the latest version
    128 
    129 ```bash
    130 git fetch origin
    131 ```
    132 
    133 The last upstream version is now on `origin/main` and none of your local
    134 branches have been modified by this command.
    135 
    136 ### Start a new branch
    137 
    138 To start a new change you need a local branch. Each branch will represent a list
    139 of individual commits which can then be requested to be merged as a single merge
    140 request. So in general one branch is one code review, but each branch can have
    141 multiple individual commits in it.
    142 
    143 ```bash
    144 git checkout origin/main -b mybranch
    145 ```
    146 
    147 This will create a new branch `mybranch` tracking `origin/main`. A branch can
    148 track any remove or local branch, which is used by some tools. Running `git
    149 branch -vv` will show all the branches you have have, what are they tracking and
    150 how many commits are ahead or behind. If you create a branch without tracking
    151 any other, you can add or change the tracking branch of the current branch
    152 running `git branch --set-upstream-to=...`.
    153 
    154 ### Add changes to your branch
    155 
    156 Follow any of the many online tutorials, for example
    157 [The basics](https://git-scm.com/book/en/v2/Git-Basics-Getting-a-Git-Repository)
    158 chapter from the https://git-scm.com/doc website is a good starting guide.
    159 Create, change or delete files and do a git commit with a message.
    160 
    161 The commit message is required. A commit message should follow the 50/72 rule:
    162 
    163 *   First line is 50 characters or less.
    164 *   Then a blank line.
    165 *   Remaining text should be wrapped at 72 characters.
    166 
    167 The first line should identify your commit, since that's what most tools will
    168 show to the user. First lines like "Some fixes" are not useful. Explain what the
    169 commit contains and why.
    170 
    171 We follow the [Google C++ Coding
    172 Style](https://google.github.io/styleguide/cppguide.html). A
    173 [clang-format](https://clang.llvm.org/docs/ClangFormat.html) configuration
    174 file is available to automatically format your code, you can invoke it with
    175 the `./ci.sh lint` helper tool.
    176 
    177 Read the [CONTRIBUTING.md](../CONTRIBUTING.md) file for more information about
    178 contributing to libjxl.
    179 
    180 ### Upload your changes for review
    181 
    182 The first step is a local review of your changes to see what will you be sending
    183 for review. `gitg` is a nice Gtk UI for reviewing your local changes, or `tig`
    184 for similar ncurses console-based interface. Otherwise, from the terminal you
    185 can run:
    186 
    187 ```bash
    188 git branch -vv
    189 ```
    190 
    191 To show the current status of your local branches. In particular, since your
    192 branch is tracking origin/main (as seen in the output) git will tell you that
    193 you are one commit ahead of the tracking branch.
    194 
    195 ```
    196 * mybranch       e74ae1a [origin/main: ahead 1] Improved decoding speed by 40%
    197 ```
    198 
    199 It is a good idea before uploading to sync again with upstream (`git fetch
    200 origin`) and then run `git branch -vv` to check whether there are new changes
    201 upstream. If that is the case, you will see a "behind" flag in the output:
    202 
    203 ```
    204 * mybranch       e74ae1a [origin/main: ahead 1, behind 2] Improved decoding speed by 40%
    205 ```
    206 
    207 To sync your changes on top of the latest changes in upstream you need to
    208 rebase:
    209 
    210 ```bash
    211 git rebase
    212 ```
    213 
    214 This will by default rebase your current branch changes on top of the tracking
    215 branch. In this case, this will try to apply the current commit on top of the
    216 latest origin/main (which has 2 more commits than the ones we have in our
    217 branch) and your branch will now include that. There could be conflicts that you
    218 have to deal with. A shortcut to do both fetch and rebase is to run `git pull
    219 -r`, where the `-r` stands for "rebase" and will rebase the local commits on top
    220 of the remote ones.
    221 
    222 Before uploading a patch, make sure your patch conforms to the
    223 [contributing guidelines](../CONTRIBUTING.md) and it
    224 [builds and passes tests](building_and_testing.md).
    225 
    226 Once you are ready to send your branch for review, upload it to *your* fork:
    227 
    228 ```bash
    229 git push origin mybranch
    230 ```
    231 
    232 This will push your local branch "mybranch" to a remote in your fork called
    233 "mybranch". The name can be anything, but keep in mind that it is public. A link
    234 to the URL to create a pull request will be displayed.
    235 
    236 ```
    237 Enumerating objects: 627, done.
    238 Counting objects: 100% (627/627), done.
    239 Delta compression using up to 56 threads
    240 Compressing objects: 100% (388/388), done.
    241 Writing objects: 100% (389/389), 10.71 MiB | 8.34 MiB/s, done.
    242 Total 389 (delta 236), reused 0 (delta 0)
    243 emote:
    244 remote: Create a pull request for 'mybranch' on GitHub by visiting:
    245 remote:      https://github.com/{{USERNAME}}/libjxl/pull/new/mybranch
    246 remote:
    247 To github.com:{{USERNAME}}/libjxl.git
    248  * [new branch]      mybranch -> mybranch
    249 ```
    250 
    251 ### Updating submodules
    252 
    253 The repository uses submodules for external library dependencies in
    254 third_party. Each submodule points to a particular external commit of the
    255 external repository by the hash code of that external commit. Just like
    256 regular source code files, this hash code is part of the current branch and
    257 jpeg xl commit you have checked out.
    258 
    259 When changing branches or when doing `git rebase`, git will unfortunately
    260 *not* automatically set those hashes to the ones of the branch or jpeg xl
    261 commit you changed to nor set the source files of the third_party submodules
    262 to the new state. That is, even though git will have updated the jpeg xl
    263 source code files on your disk to the new ones, it will leave the submodule
    264 hashes and the files in third_party in your workspace to the ones they were
    265 before you changed branches. This will show up in a git diff because this
    266 is seen as a change compared to the branch you switched to. The git diff shows
    267 the difference in hash codes (as if you are changing to the old ones), it does
    268 not show changes in files inside the third_party directory.
    269 
    270 This mismatch can cause at least two problems:
    271 
    272 *) the jpeg xl codebase may not compile due to third_party library version
    273 mismatch if e.g. API changed or a submodule was added/removed.
    274 
    275 *) when using `commit -a` your commit, which may be a technical change
    276 unrelated to submodule changes, will unintentionally contain a change to the
    277 submodules hash code, which is undesired unless you actually want to change
    278 the version of third_party libraries.
    279 
    280 To resolve this, the submodules must be updated manually with
    281 the following command after those actions (at least when the submodules
    282 changed):
    283 
    284 ```
    285 git submodule update --init --recursive
    286 ```
    287 
    288 Here, the init flag ensures new modules get added when encessary and the
    289 recursive flag is required for the submodules depending on other submodules.
    290 
    291 If you checkout a different branch, you can spot that submodules changed
    292 when it shows a message similar to this:
    293 
    294 ```
    295 M       third_party/brotli
    296 M       third_party/lcms
    297 ```
    298 
    299 If you do a rebase you may end up in a harder to solve situation, where
    300 `git submodule update --init --recursive` itself fails with errors such as:
    301 
    302 ```
    303 Unable to checkout '35ef5c554d888bef217d449346067de05e269b30' in submodule path 'third_party/brotli'
    304 ```
    305 
    306 In that case, you can use the force flag:
    307 
    308 ```
    309 git submodule update --init --recursive --force
    310 ```
    311 
    312 ### Iterating changes in your pull request
    313 
    314 To address reviewer changes you need to amend the local changes in your branch
    315 first. Make the changes you need in your commit locally by running `git commit
    316 --amend file1 file2 file3 ...` or `git commit --amend -a` to amend all the
    317 changes from all the staged files.
    318 
    319 Once you have the new version of the "mybranch" branch to re-upload, you need to
    320 force push it to the same branch in your fork. Since you are pushing a different
    321 version of the same commit (as opposed to another commit on top of the existing
    322 ones), you need to force the operation to replace the old version.
    323 
    324 ```bash
    325 git push origin mybranch --force
    326 ```
    327 
    328 The pull request should now be updated with the new changes.
    329 
    330 ### Merging your changes
    331 
    332 We use "rebase" as a merge policy, which means that there a no "merge" commits
    333 (commits with more than one parent) but instead only a linear history of
    334 changes.
    335 
    336 It is possible that other changes where added to the main branch since the last
    337 time you rebased your changes. These changes could create a conflict with your
    338 Pull Request, if so you need to `git fetch`, `git rebase` and push again your
    339 changes which need to go through the continuous integration workflow again to
    340 verify that all the tests pass again after including the latest changes.
    341 
    342 ### Trying locally a pending Pull Request
    343 
    344 If you want to review in your computer a pending pull request proposed by
    345 another user you can fetch the pull request commit with the following command,
    346 replacing `NNNN` with the pull request number:
    347 
    348 ```bash
    349 git fetch origin refs/pull/NNNN/head
    350 git checkout FETCH_HEAD
    351 ```
    352 
    353 The first command will add to your local git repository the remote commit for
    354 the pending pull request and store a temporary reference called `FETCH_HEAD`.
    355 The second command then checks out that reference. From this point you can
    356 review the files in your computer, create a local branch for this FETCH_HEAD or
    357 build on top of it.