<style> /* Formatting for the title slide */ .title { text-align: center; } /* Formatting for body text */ section { font-size: 36px; text-align: left; } /* Formatting for image credits */ .credit { font-size: 10px; } /* Formatting for columns of content */ .columns { column-count: 2; text-align: justify; } /* Formatting for code blocks */ code { /* Automatic line wrapping */ white-space : pre-wrap !important; } </style> ## Intermediate Git and GitHub #### Assumed knowledge In this course, we assume familiarity with the following Git commands and GitHub concepts: * `add`, `commit`, `push`, `pull`, `log` * Issues * Pull requests (PRs) If these are new to you then please join the *Introduction to Git and GitHub for Beginners* course, which is running in parallel. <!-- Presenter notes: Have this slide up for the first 5 minutes while people arrive. --> --- <div class="title"> # Intermediate Git and GitHub Joe Wallwork and Tom Meltzer Slides: https://hackmd.io/@jwallwork/2024-07-10-intermediate-git-tools?type=slide GitHub repo: https://github.com/Cambridge-ICCS/intermediate-git-iccs-summer-school-2024 </div> --- ## Contents 1. Branching and conflicts. 2. Intermediate Git commands. 3. Software engineering with GitHub. 4. Tips, tricks, and fun stuff! --- ## GitHub <i class="fa fa-github"></i> Navigate to the GitHub repo: https://github.com/Cambridge-ICCS/intermediate-git-iccs-summer-school-2024 #### Exercises 1. Check you are happy with the contents of the README. 2. Create a fork of the repo under your username. 3. Clone your fork to your local machine. <!-- Presenter notes: Navigate to the repository, show the README, and ask to take a look around. Allow 5 minutes for this task and then give a quick tour. --> --- # 1. Branching and conflicts --- ## Branching basics The `main` branch is protected in our repo, meaning contributors cannot push directly to it. (More on this later.) To contribute to `main`, create a branch for your developments and open a PR when it's ready. <img src="https://hackmd.io/_uploads/ryQ9nibPC.svg" alt="git_branching.drawio" width="600"/> --- ## Branching basics The `main` branch is protected in our repo, meaning contributors cannot push directly to it. (More on this later.) To contribute to `main`, create a branch for your developments and open a PR when it's ready. <img src="https://hackmd.io/_uploads/ryQ9nibPC.svg" alt="basic_branch.drawio" width="600"/> :::info :bulb: Shortcut to create a new branch and switch to it: `git switch -c <branchname>` ::: --- ## Branch-of-branch Suppose `mybranch` adds a significant new feature. What if you spot a bug and have a fix for it? <img src="https://hackmd.io/_uploads/ByC62j-w0.svg" alt="branch_of_branch.drawio.drawio" width="800"/> --- ## `develop` branch Large codes often have a `develop` branch in addition to the `main` branch. <img src="https://hackmd.io/_uploads/Hy8baiZwC.svg" alt="develop_branch.drawio" width="800"/> --- ## Merge conflicts What if two branches modify the same part of a file? <img src="https://hackmd.io/_uploads/B1RETsZw0.svg" alt="merge_conflict.drawio" width="800"/> --- ## Merge conflict example Consider the following enhancements to `equation_of_line`: [#12](https://github.com/Cambridge-ICCS/intermediate-git-iccs-summer-school-2024/pull/12): Implement Lagrange polynomial approach. [#13](https://github.com/Cambridge-ICCS/intermediate-git-iccs-summer-school-2024/pull/13): Check that the points provided differ. [#14](https://github.com/Cambridge-ICCS/intermediate-git-iccs-summer-school-2024/pull/14): Implement SymPy approach. <!-- Presenter notes: 1. The first merge will be fine. 2. The second merge will be fine. 3. The third merge will hit a conflict! When we hit the conflict, we have to decide what to do. Options: a) Drop the SymPy change because we don't want another dependency. b) Drop the error check because SymPy does it anyway. c) Use both because we want our own error check. --> --- # 2. Intermediate Git commands --- ## Checking state: `git status` Snapshot of changes staged and not staged for commit. ```git On branch mybranch Your branch is up-to-date with 'origin/mybranch'. Changes to be committed: (use "git restore --staged <file>..." to unstage) deleted: README.md renamed: maths.py -> mathematics.py new file: physics.py Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: test_maths.py Untracked files: (use "git add <file>..." to include in what will be committed) tmp.patch TODO ``` :::info :bulb: Check this regularly! ::: --- ## Checking state: `git diff` ![image](https://hackmd.io/_uploads/rkhvK17LA.png) Useful but not meant for human consumption :male-detective: :::info :bulb: See also `git show <branch/commit-hash>` ::: --- ## Checking state: `git difftool` ![image](https://hackmd.io/_uploads/rke8FymIC.png) - Syntax highlighting AND context - Much easier to read :eyes: --- ## Checking state: `git difftool` Configure by adding the following to your `~/.gitconfig`: ```gitconfig [diff] tool = vimdiff [difftool] prompt = false ``` Or run these commands: ```git git config --global diff.tool vimdiff git config --global difftool.prompt false ``` :::info :keyboard: **Exercise** Configure using one of the methods above. `git switch `[`example-diff`](https://github.com/Cambridge-ICCS/intermediate-git-iccs-summer-school-2024/tree/example-diff) `git diff 2df42ae` `git difftool 2df42ae` ::: --- ## Temporary work: `git patch` I need to put aside temporary work and do some branch manipulations. How? ```sh git diff > my_patch.patch # Stash your current changes git restore . # Restore latest commit # <Do the required branch manipulations> git apply my_patch.patch # Reapply changes from the patch ``` <!-- Presenter notes: Patch files were introduced before centralised version control systems. Contributors could email patch files to provide updates to a codebase. --> --- ## Temporary work: `git patch` I need to put aside temporary work and do some branch manipulations. How? ```sh git diff > my_patch.patch # Stash your current changes git restore . # Restore latest commit # <Do the required branch manipulations> git apply my_patch.patch # Reapply changes from the patch ``` :::info :bulb: Apply patch in reverse: `git apply -R my_patch.patch` ::: --- ## Temporary work: `git patch` I need to put aside temporary work and do some branch manipulations. How? ```sh git diff > my_patch.patch # Stash your current changes git restore . # Restore latest commit # <Do the required branch manipulations> git apply my_patch.patch # Reapply changes from the patch ``` :::warning :house: **Subversion users: do try this at home** `svn diff > svn.patch && git apply svn.patch` `git diff > git.patch && svn patch git.patch` ::: --- ## Temporary work: `git stash` *Why do I keep finding `tmp.patch` files everywhere?* Stashing changes puts them on the *stack*. <div class="columns"> ```sh git stash # <Do the required branch manipulations> git stash pop ``` ![stack](https://hackmd.io/_uploads/ryV3YFdIR.svg) </div> `git stash list` ```git stash@{0}: WIP on impl3: 8895c93 Add SymPy as a dependency stash@{1}: WIP on check_points_differ: a92866d Raise error if points are identical stash@{2}: WIP on main: a58ff9a Merge pull request #9 from Cambridge-ICCS/impl1 ``` --- ## Editing history: `git rebase` :trophy: Some common problems: 1. I want to drop some commits from my branch. 2. I want to reword a commit message. 3. I want to squash some commits in my branch. 4. I want to change the 'base' of my branch to start at the head of another branch. All these things (and more) can be done with `git rebase` - one of the most powerful Git tools. --- ## Editing history: `git rebase` :trophy: *I want to change the 'base' of my branch to start at the head of another branch.* Consider the simple case of upgrading to a later version. <img src="https://hackmd.io/_uploads/HkhOg2bv0.svg" alt="rebase.drawio" width="800"/> --- ## Editing history: `git rebase` :trophy: Some common problems: 1. I want to drop some commits from my branch. 2. I want to reword a commit message. 3. I want to squash some commits in my branch. 4. I want to change the 'base' of my branch to start at the head of another branch. :::info :keyboard: **Exercise** Run an interactive rebase (`git rebase -i <target>`) on branch [`rebase-exercise`](https://github.com/Cambridge-ICCS/intermediate-git-iccs-summer-school-2024/tree/rebase-exercise) to complete tasks 1-4. ::: <!-- Demonstrator notes: Point out the help text! Discuss rebase vs merge. --> --- ## Editing history: `git reflog` Ahh, my rebase broke things! How can I reverse it? ```auto! 92d0571 (HEAD -> rebase-exercise, origin/rebase-exercise) HEAD@{0}: commit: Instructions for task 4 e6509be HEAD@{1}: commit: Drop this commit 3131c09 HEAD@{2}: commit: Reword this commit message 007117a HEAD@{3}: commit: Squash this commit into the previous one 09a6337 HEAD@{4}: commit: Squash the following commit into this one 93212e5 (origin/main, origin/HEAD, main) HEAD@{5}: checkout: moving from main to rebase-exercise ``` Go back to an earlier state with (for example) `git reset --hard 3131c09`. Note that the `reset` goes in the `reflog`, too! :::danger :warning: **Warning** The `--hard` option is potentially destructive. ::: --- # 3. Software engineering with GitHub --- ## GitHub: Project boards The example repository has a [Project Board](https://github.com/orgs/Cambridge-ICCS/projects/34/views/1) for planning and tracking progress. :::success :computer: **Live demo** ::: :::info :keyboard: **Exercise** Try setting up a project board for your fork. ::: Note: project boards are associated with users or organisations, rather than repositories. <!-- Presenter notes: * Show how to remove limits on numbers of issues in each column. * Note including the following in the PR text box: `Closes #<ISSUE_NUMBER>`. * Add "review required" and "blocked" columns. * Discuss milestones. If there is time for the exercise then leave 5 minutes for this. --> --- ## GitHub Actions: cloud testing From [Wikipedia](https://en.wikipedia.org/wiki/Continuous_integration): > Continuous integration (CI) is the practice of integrating source code changes frequently and ensuring that the integrated codebase is in a workable state. CI testing is the part that ensures the codebase is in a 'workable state'. This was added to the example repo in [#9](https://github.com/Cambridge-ICCS/intermediate-git-iccs-summer-school-2024/pull/9). <!-- Presenter notes: Go to the PR and walk through changes. Discuss how tests initially failed and we were able to spot a typo. --> --- ## GitHub: Files to always include * `LICENSE`: Sets out how the code may be interacted with (e.g., can it be redistributed?) * `README.md`: Tells users what the repository is for and important details about its usage (e.g., installation instructions). --- ## GitHub: Settings to always use * Protect `main` branch. * Ensure tests pass before merging PRs. * Require PR approvals. * Do not allow bypassing rules. :::info :keyboard: **Exercise** Set these up on your fork of the example repository. Hint: [https://github.com/<username>/intermediate-git-iccs-summer-school-2024/settings/branches](https://github.com/Cambridge-ICCS/intermediate-git-iccs-summer-school-2024/settings/branches) ::: <!-- Allow 5 minutes for the exercise then click the link to demo what would be required. --> --- ## Debugging on GitHub Actions Debug GitHub Actions using [tmate](https://github.com/mxschmitt/action-tmate) ```yaml name: CI on: [push] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup tmate session uses: mxschmitt/action-tmate@v3 ``` :::success :computer: **Live demo** ::: :::warning :house: **Do try this at home** ::: --- # 4. Tips, tricks, and fun stuff! *The following slides are for information. We might not get to them in the live course.* --- ## `git bisect`: a debugging life-saver A bug was introduced somewhere in the development process, but it's unclear when. What do I do? :shrug: ![bisect-curve](https://hackmd.io/_uploads/B1OXz8SPA.png) :::warning :house: **Do try this at home** https://github.com/TomMelt/git-bisect-demo ::: <!-- Presenter notes: Live demo requires around 20 minutes. --> --- ## GitHub Container Registry * Like DockerHub but easier to integrate with GitHub * Store container images on your account * Inherit project permissions or set granular permissions ```yaml runs-on: ubuntu-latest container: image: ghcr.io/<YOUR_USERNAME>/<IMAGE_NAME>:<IMAGE_TAG> credentials: username: <YOUR_USERNAME> password: ${{ secrets.DOCKER_CONTAINER_REGISTRY_TOKEN }} ``` :::info For more info, please see GitHub's [documentation](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#about-the-container-registry) ::: --- ## `.gitignore` Does this `git status` look familiar to anyone? ```git On branch main Your branch is up-to-date with 'origin/main'. Untracked files: (use "git add <file>..." to include in what will be committed) FIXME Notes.txt TODO __pycache__/ a.out job.err job.out maths.py.swp output.nc test_maths.py.swp tmp.patch tmp2.patch ``` --- ## `.gitignore` Ignore certain subdirectories, filename patterns, and/or extensions with a `.gitignore` file. For example: ```git # Directories __pycache__/ # Other common files FIXME NOTES Notes.txt TODO # File extensions *.*.swp *.err *.nc *.out *.patch *.pyc ``` --- ## `git config` Recall how we configured `git difftool` with a `.gitconfig` file. We can do the same for other Git commands: ```gitconfig [user] name = Joe Bloggs # User credentials to be used in email = j.bloggs@blogco.com # commits [init] defaultBranch = trunk # Default branch other than 'main' [core] commentChar = & # Comment character other than '#' excludesFile = ~/.gitignore # Global .gitignore file [column] ui = auto # Allow multi-column output [alias] ci = commit # Aliases/shortcuts for Git commands co = checkout # (Any subversion users in the st = status # room?) ``` --- ## Fun stuff :balloon: :::warning :house: **Do try these at home** * `git blame` * `git commit -p` * `git log -p` * `git diff --name-only` * `git diff --word-diff` * [Semantic commit messages](https://gist.github.com/joshbuchea/6f47e86d2510bce28f8e7f42ae84c716) ::: <!-- * [Git butler](https://gitbutler.com/) --> --- # Thank you for attending!
{"description":"Software engineering using Git and GitHub for intermediate users.","title":"Intermediate Git and GitHub","contributors":"[{\"id\":\"033ac354-bcb8-4c50-8db3-75282f8d798a\",\"add\":22989,\"del\":9383},{\"id\":\"dc15f293-368c-4ca5-9e71-50ccc99f6028\",\"add\":1297,\"del\":500}]"}
    592 views