################################################################################ ┏━╸╻╺┳╸ ╻ ╻┏━┓┏━┓╻┏ ┏━┓╻ ╻┏━┓┏━┓ ┃╺┓┃ ┃ ╺━╸ ┃╻┃┃ ┃┣┳┛┣┻┓┗━┓┣━┫┃ ┃┣━┛ ┗━┛╹ ╹ ┗┻┛┗━┛╹┗╸╹ ╹┗━┛╹ ╹┗━┛╹ 27. September 2022 Pranger Stefan ################################################################################ ┏━┓┏━┓┏━┓╺┳┓┏┳┓┏━┓┏━┓ ┣┳┛┃ ┃┣━┫ ┃┃┃┃┃┣━┫┣━┛ ╹┗╸┗━┛╹ ╹╺┻┛╹ ╹╹ ╹╹ - git basics, what is git capable of - what do to in what situations - project management - pull requests and feature branches - bug tracking - continuous integration - git gadgets (grep, bisect, etc.) ################################################################################ ┏┳┓┏━┓╻┏┓╻ ┏━┓┏━┓╻┏┓╻╺┳╸┏━┓ ┃┃┃┣━┫┃┃┗┫ ┣━┛┃ ┃┃┃┗┫ ┃ ┗━┓ ╹ ╹╹ ╹╹╹ ╹ ╹ ┗━┛╹╹ ╹ ╹ ┗━┛ - Staging Area and - Interactive Rebasing for well crafted commits, - Merging and Rebasing, - Pull Request workflow and - Git as inspection tool. ################################################################################ ┏━╸╻╺┳╸ ┏┓ ┏━┓┏━┓╻┏━╸┏━┓ ┃╺┓┃ ┃ ┣┻┓┣━┫┗━┓┃┃ ┗━┓ ┗━┛╹ ╹ ┗━┛╹ ╹┗━┛╹┗━╸┗━┛ - _distributed_ version control - staging area - git add, git reset, etc. instead of only commiting - branching - "killer feature" - content-addressable filesystem ################################################################################ ┏━╸╻╺┳╸ ╻┏┓╻╻╺┳╸ ┃╺┓┃ ┃ ┃┃┗┫┃ ┃ ┗━┛╹ ╹ ╹╹ ╹╹ ╹ Create or clone a repository via - $ git init - $ git clone Basic configuration: - $ git config --global user.name "Foo Bar" - $ git config --global user.email foobar@example.com ################################################################################ ┏━┓╺┳╸┏━┓┏━╸╻┏┓╻┏━╸ ┏━┓┏━┓┏━╸┏━┓ ┗━┓ ┃ ┣━┫┃╺┓┃┃┗┫┃╺┓ ┣━┫┣┳┛┣╸ ┣━┫ ┗━┛ ╹ ╹ ╹┗━┛╹╹ ╹┗━┛ ╹ ╹╹┗╸┗━╸╹ ╹ - first main difference to SVN - advantage of git Files can be: ┌─────────┐ ┌──────────┐ ┌────────┐ ┌──────┐ ┌────────┐ │Untracked│ │Unmodified│ │Modified│ │Staged│ │Commited│ └─────────┘ └──────────┘ └────────┘ └──────┘ └────────┘ Git manages these states as: ┌─────────────────┐ ┌─────┐ ┌────┐ │Working Directory│ │Index│ │HEAD│ └─────────────────┘ └─────┘ └────┘ Your Sandbox The proposed The next next commit parent ################################################################################ ┏━┓╺┳╸┏━┓┏━╸╻┏┓╻┏━╸ ┏━┓┏━┓┏━╸┏━┓ ┗━┓ ┃ ┣━┫┃╺┓┃┃┗┫┃╺┓ ┣━┫┣┳┛┣╸ ┣━┫ ┗━┛ ╹ ╹ ╹┗━┛╹╹ ╹┗━┛ ╹ ╹╹┗╸┗━╸╹ ╹ - git add - git add --patch (-p) - add individual lines (hunks) to commits - "interactive staging" - very useful to craft commits that are easy to understand - git restore --staged/--worktree - git reset --soft/--mixed/--hard - git rm --cached ################################################################################ ┏━┓╺┳╸┏━┓┏━╸╻┏┓╻┏━╸ ┏━┓┏━┓┏━╸┏━┓ ┗━┓ ┃ ┣━┫┃╺┓┃┃┗┫┃╺┓ ┣━┫┣┳┛┣╸ ┣━┫ ┗━┛ ╹ ╹ ╹┗━┛╹╹ ╹┗━┛ ╹ ╹╹┗╸┗━╸╹ ╹ Check your modifications or what you are about to commit - git diff / git diff --staged Should help to have a clean process of commiting changes Finalizing step: git commit What if I messed up my current commit? - $ git commit --amend ################################################################################ ┏━╸╻╺┳╸ ┏━┓┏┓ ┏┓┏━╸┏━╸╺┳╸┏━┓ ┃╺┓┃ ┃ ┃ ┃┣┻┓ ┃┣╸ ┃ ┃ ┗━┓ ┗━┛╹ ╹ ┗━┛┗━┛┗━┛┗━╸┗━╸ ╹ ┗━┛ ┌────────────────┐ ┌──────────────────────┐main.c┌────┐ │commit (b3aacfe)│───>│tree (think directory)│─────>│blob│ └────────────────┘ └──────────────────────┘ └────┘ | parent \ v \ ┌────────────────┐ ┌──────────────────────┐ \ ┌──>│commit (a21fh1a)│───>│ tree │ \ | └────────────────┘ └──────────────────────┘ \ ┌───┐ / | \ \ │tag│ main.c config.h main.h \ └───┘ / | \ \ ┌────┐ ┌────┐ ┌────┐<--° │blob│ │blob│<-┐ │blob│ | └────┘ └────┘ \ └────┘ | └───────────┘ ################################################################################ ┏━┓┏━╸╻ ╻╻┏━┓╻┏━┓┏┓╻ ┏━┓┏━╸╻ ┏━╸┏━╸╺┳╸╻┏━┓┏┓╻ ┣┳┛┣╸ ┃┏┛┃┗━┓┃┃ ┃┃┗┫ ┗━┓┣╸ ┃ ┣╸ ┃ ┃ ┃┃ ┃┃┗┫ ╹┗╸┗━╸┗┛ ╹┗━┛╹┗━┛╹ ╹ ┗━┛┗━╸┗━╸┗━╸┗━╸ ╹ ╹┗━┛╹ ╹ ┌────────────────┐ │commit (b3aacfe)│ └────────────────┘ - $ git show -- - commits are referencable via - their SHA1 - HEAD - tags/branchnames - Syntax: - HEAD~ // select the n-th ancestor of HEAD - .. - HEAD-history: - HEAD@{} ################################################################################ ┏┓ ┏━┓┏━┓┏┓╻┏━╸╻ ╻╻┏┓╻┏━╸ ┣┻┓┣┳┛┣━┫┃┗┫┃ ┣━┫┃┃┗┫┃╺┓ ┗━┛╹┗╸╹ ╹╹ ╹┗━╸╹ ╹╹╹ ╹┗━┛ - git's "killer feature" - A new branch is essentially just opening a new history (i.e. no copying involved!) - Highly encouraged to use many (shortlived) branches Create a new branch with - $ git switch --create/-c ################################################################################ ┏┓ ┏━┓┏━┓┏┓╻┏━╸╻ ╻╻┏┓╻┏━╸ ┣┻┓┣┳┛┣━┫┃┗┫┃ ┣━┫┃┃┗┫┃╺┓ ┗━┛╹┗╸╹ ╹╹ ╹┗━╸╹ ╹╹╹ ╹┗━┛ Switching between branches with - $ git switch - $ git switch - Cannot switch if that would overwrite modifications Untracked files will simply "move along" Delete or rename a branch: - $ git branch -d - $ git branch -m ################################################################################ ┏━╸╻╺┳╸ ┏━┓╺┳╸┏━┓┏━┓╻ ╻ ┃╺┓┃ ┃ ┗━┓ ┃ ┣━┫┗━┓┣━┫ ┗━┛╹ ╹ ┗━┛ ╹ ╹ ╹┗━┛╹ ╹ Very helpful to quickly safe modifications - $ git stash push --message/-m "..." - $ git stash list - $ git stash apply/pop ################################################################################ ┏━╸╻╺┳╸ ┏━┓╺┳╸┏━┓┏━┓╻ ╻ ┃╺┓┃ ┃ ┗━┓ ┃ ┣━┫┗━┓┣━┫ ┗━┛╹ ╹ ┗━┛ ╹ ╹ ╹┗━┛╹ ╹ $ git stash push -m "WIP some frontend feature" $ git switch stable ... $ git commit $ git switch frontend_feature $ git stash pop ################################################################################ ╻┏┓╻╺┳╸┏━╸┏━┓┏━┓┏━╸╺┳╸╻╻ ╻┏━╸ ┏━┓┏━╸┏┓ ┏━┓┏━┓╻┏┓╻┏━╸ ┃┃┗┫ ┃ ┣╸ ┣┳┛┣━┫┃ ┃ ┃┃┏┛┣╸ ┣┳┛┣╸ ┣┻┓┣━┫┗━┓┃┃┗┫┃╺┓ ╹╹ ╹ ╹ ┗━╸╹┗╸╹ ╹┗━╸ ╹ ╹┗┛ ┗━╸ ╹┗╸┗━╸┗━┛╹ ╹┗━┛╹╹ ╹┗━┛ - $ git rebase -i Can be used to cleanup commit history - allows to basically change the history of your commits - each project should have a guideline - small feature may for example be _squashed_ together - WIP- or unnecessary commits can be removed - remove _checkpoint commits_ -> $ git rebase -i my_current_feature@{24.hours.ago}~1 ################################################################################ ╻┏┓╻╺┳╸┏━╸┏━┓┏━┓┏━╸╺┳╸╻╻ ╻┏━╸ ┏━┓┏━╸┏┓ ┏━┓┏━┓╻┏┓╻┏━╸ ┃┃┗┫ ┃ ┣╸ ┣┳┛┣━┫┃ ┃ ┃┃┏┛┣╸ ┣┳┛┣╸ ┣┻┓┣━┫┗━┓┃┃┗┫┃╺┓ ╹╹ ╹ ╹ ┗━╸╹┗╸╹ ╹┗━╸ ╹ ╹┗┛ ┗━╸ ╹┗╸┗━╸┗━┛╹ ╹┗━┛╹╹ ╹┗━┛ # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message ... # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. ################################################################################ ┏━┓┏━╸┏┳┓┏━┓╺┳╸┏━╸┏━┓ ┣┳┛┣╸ ┃┃┃┃ ┃ ┃ ┣╸ ┗━┓ ╹┗╸┗━╸╹ ╹┗━┛ ╹ ┗━╸┗━┛ Remote server to share code base - Gets setup with $ git clone - $ git remote add - $ git fetch - $ git pull - $ git push ################################################################################ ┏┳┓┏━╸┏━┓┏━╸╻┏┓╻┏━╸ ┃┃┃┣╸ ┣┳┛┃╺┓┃┃┗┫┃╺┓ ╹ ╹┗━╸╹┗╸┗━┛╹╹ ╹┗━┛ Multiple parallel workflows are encouraged -> unavoidable conflicts - Project guideline on how to handle conflicts - For more advanced usage: - $ git rerere - different merging strategies ################################################################################ ┏┳┓┏━╸┏━┓┏━╸╻┏┓╻┏━╸ ┏━╸┏━╸ ┃┃┃┣╸ ┣┳┛┃╺┓┃┃┗┫┃╺┓ ╺━╸ ┣╸ ┣╸ ╹ ╹┗━╸╹┗╸┗━┛╹╹ ╹┗━┛ ╹ ╹ - _fast-forward_ merge possible if HEAD direct ancestor - This allows for a clean, linear history on stable branches - helps with git blame, git bisect, git rebase -i ┌─────────────────────────────────────────────────────────────┐ │[spranger@gitWorkshop/stagingArea] git merge more_int_changes│ │Updating eff74ed..a2c365a │ │Fast-forward │ │ testfile1 | 4 ++-- │ │ 1 file changed, 2 insertions(+), 2 deletions(-) │ └─────────────────────────────────────────────────────────────┘ - --ff, --no-ff, --ff-only ################################################################################ ┏━┓┏━╸┏┓ ┏━┓┏━┓╻┏┓╻┏━╸ ┣┳┛┣╸ ┣┻┓┣━┫┗━┓┃┃┗┫┃╺┓ ╹┗╸┗━╸┗━┛╹ ╹┗━┛╹╹ ╹┗━┛ Allows to move bases of branches (and more) - Most common usage: Update the base of your branch if outdated - Common strategy to _always_ ensure fast-forward merges - Very helpful in complicated branching settings Important Note: ┌─────────────────────────────────────────────────────────┐ │Do not rebase commits that exist outside your repository │ │ and that people (may) have based work on. │ └─────────────────────────────────────────────────────────┘ ################################################################################ ┏━╸┏━┓┏┓╻┏━╸╻ ╻┏━╸╺┳╸┏━┓ ┃ ┃ ┃┃┗┫┣╸ ┃ ┃┃ ┃ ┗━┓ ┗━╸┗━┛╹ ╹╹ ┗━╸╹┗━╸ ╹ ┗━┛ Git tracks (per hunk-) conflicts over three files: - base/common - ours - theirs - $ git config --global merge.conflictstyle diff3 - Often helpful to have common state ################################################################################ ┏━╸┏━┓┏┓╻┏━╸╻ ╻┏━╸╺┳╸┏━┓ ┃ ┃ ┃┃┗┫┣╸ ┃ ┃┃ ┃ ┗━┓ ┗━╸┗━┛╹ ╹╹ ┗━╸╹┗━╸ ╹ ┗━┛ ┌────────────────────────┐ ┌────────────────────────┐ │ #include │ │ int main() { │ │ <<<<<<< HEAD │ │ int a = 5; │ │ #include │ │ <<<<<<< HEAD │ │ ||||||| 9275968 │ │ int b = 4; │ │ ======= │ │ ||||||| 9275968 │ │ #include │ │ int b = 8; │ │>>>>>>> new_feature │ │ ======= │ └────────────────────────┘ │ int b = 9; │ │ >>>>>>> new_feature │ └────────────────────────┘ - Conflict markers appear in the file itself - Simplest way to handle: -> directly modify the file - Git difftool for visual conflict resolving ################################################################################ ╺┳╸┏━╸┏━┓┏┳┓ ╻ ╻┏━┓┏━┓╻┏ ┏━╸╻ ┏━┓╻ ╻┏━┓ ┃ ┣╸ ┣━┫┃┃┃ ┃╻┃┃ ┃┣┳┛┣┻┓┣╸ ┃ ┃ ┃┃╻┃┗━┓ ╹ ┗━╸╹ ╹╹ ╹ ┗┻┛┗━┛╹┗╸╹ ╹╹ ┗━╸┗━┛┗┻┛┗━┛ Team Workflows: - Merge vs. Rebase - Only fast-forward? - Keep merge commits? Branching Strategies: - Main - Development - Feature branches - Stable branches - Main - Feature branches - etc. ################################################################################ ┏━╸┏━┓╻ ╻ ┏━┓┏┓ ┏━┓┏━┓┏━┓╺┳╸╻┏━┓┏┓╻ ┃ ┃ ┃┃ ┃ ┣━┫┣┻┓┃ ┃┣┳┛┣━┫ ┃ ┃┃ ┃┃┗┫ ┗━╸┗━┛┗━╸┗━╸╹ ╹┗━┛┗━┛╹┗╸╹ ╹ ╹ ╹┗━┛╹ ╹ Git usage in the bigger picture. - Issue tracking, - Pull Request handling, - Assigning work, - Milestones, Projects, etc. Example frontends: - GitHub - Gitlab - Gitea - Gogs ################################################################################ ╻┏━┓┏━┓╻ ╻┏━╸ ╺┳╸┏━┓┏━┓┏━╸╻┏ ┏━╸┏━┓ ┃┗━┓┗━┓┃ ┃┣╸ ┃ ┣┳┛┣━┫┃ ┣┻┓┣╸ ┣┳┛ ╹┗━┛┗━┛┗━┛┗━╸ ╹ ╹┗╸╹ ╹┗━╸╹ ╹┗━╸╹┗╸ - Note-tacking, - feature requests, - track bug reports from clients. - Use labels to categorize - bug, good-first-issue, enhancement, etc. - Associate milestones and assignees An issue should eventually be turned into a pull request (PR). ################################################################################ ┏━┓╻ ╻╻ ╻ ┏━┓┏━╸┏━┓╻ ╻┏━╸┏━┓╺┳╸┏━┓ ┣━┛┃ ┃┃ ┃ ┣┳┛┣╸ ┃┓┃┃ ┃┣╸ ┗━┓ ┃ ┗━┓ ╹ ┗━┛┗━╸┗━╸ ╹┗╸┗━╸┗┻┛┗━┛┗━╸┗━┛ ╹ ┗━┛ At the heart of your team's workflow - Accompanies a branch - Gives the team - a plattform to discuss progress, - the branches history and - a list of all introduces changes. Project lead can review and ask for changes one a line-by-line basis Basis for Continuous Integration ################################################################################ ┏━╸┏━┓┏┓╻╻ ╻┏━╸┏┓╻╺┳╸╻┏━┓┏┓╻┏━┓╻ ┏━╸┏━┓┏┳┓┏┳┓╻╺┳╸┏━┓ ┃ ┃ ┃┃┗┫┃┏┛┣╸ ┃┗┫ ┃ ┃┃ ┃┃┗┫┣━┫┃ ┃ ┃ ┃┃┃┃┃┃┃┃ ┃ ┗━┓ ┗━╸┗━┛╹ ╹┗┛ ┗━╸╹ ╹ ╹ ╹┗━┛╹ ╹╹ ╹┗━╸ ┗━╸┗━┛╹ ╹╹ ╹╹ ╹ ┗━┛ Syntax: ┌─────────────────────────────────────┐ │[optional scope]: │ │ │ │[optional body] │ │ │ │[optional footer(s)] │ └─────────────────────────────────────┘ - They enable - automated CHANGELOGs and, - automated semantic version bump and - greatly help with readability. ################################################################################ ┏━╸┏━┓┏┓╻╻ ╻┏━╸┏┓╻╺┳╸╻┏━┓┏┓╻┏━┓╻ ┏━╸┏━┓┏┳┓┏┳┓╻╺┳╸┏━┓ ┃ ┃ ┃┃┗┫┃┏┛┣╸ ┃┗┫ ┃ ┃┃ ┃┃┗┫┣━┫┃ ┃ ┃ ┃┃┃┃┃┃┃┃ ┃ ┗━┓ ┗━╸┗━┛╹ ╹┗┛ ┗━╸╹ ╹ ╹ ╹┗━┛╹ ╹╹ ╹┗━╸ ┗━╸┗━┛╹ ╹╹ ╹╹ ╹ ┗━┛ ┌──────────────────────────────────────────────────────────┐ │feat: allow provided config object to extend other configs│ │ │ │BREAKING CHANGE: `extends` key in config file is now │ │used for extending other config files │ └──────────────────────────────────────────────────────────┘ ################################################################################ ┏┳┓╻┏━┓┏━╸┏━╸╻ ╻ ┏━┓┏┓╻┏━╸┏━┓╻ ╻┏━┓ ┃┃┃┃┗━┓┃ ┣╸ ┃ ┃ ┣━┫┃┗┫┣╸ ┃ ┃┃ ┃┗━┓ ╹ ╹╹┗━┛┗━╸┗━╸┗━╸┗━╸╹ ╹╹ ╹┗━╸┗━┛┗━┛┗━┛ - Protect master branch - Repository setting for PRs help with team workflow - e.g. can be set to create merge commits. ################################################################################ ┏━┓┏┓╻┏━┓╻ ╻ ╻┏━┓╻┏━┓ ╻┏┓╻┏━┓┏━┓┏━╸┏━╸╺┳╸╻┏━┓┏┓╻ ┣━┫┃┗┫┣━┫┃ ┗┳┛┗━┓┃┗━┓ ╺━╸ ┃┃┗┫┗━┓┣━┛┣╸ ┃ ┃ ┃┃ ┃┃┗┫ ╹ ╹╹ ╹╹ ╹┗━╸ ╹ ┗━┛╹┗━┛ ╹╹ ╹┗━┛╹ ┗━╸┗━╸ ╹ ╹┗━┛╹ ╹ - Search through: code, modifications, commits or commit messages. - Look at history of lines of code - Binary search for bugs - List of most recent changes ################################################################################ ┏━╸╻╺┳╸ ╻ ┏━┓┏━╸ ┃╺┓┃ ┃ ┃ ┃ ┃┃╺┓ ┗━┛╹ ╹ ┗━╸┗━┛┗━┛ - $ git log - --patch, --after, --since, --before, --committer - -S"" // code - -L ,: // history of lines of code - -L :: // history of a function - --grep "" // commit messages - $ git log --oneline - $ git log --graph ################################################################################ ┏━╸╻╺┳╸ ┏┓ ╻ ┏━┓┏┳┓┏━╸ ┃╺┓┃ ┃ ┣┻┓┃ ┣━┫┃┃┃┣╸ ┗━┛╹ ╹ ┗━┛┗━╸╹ ╹╹ ╹┗━╸ - $ git blame ┌────────────────────────────────────────────────────────────────┐ │[spranger@gitWorkshop/stagingArea] git blame testfile1 │ │2 days ago Stefan ^3b4a655│ 1 │ #include │ │ │ 2 │ #include │ │a day ago Stefan 08b88afb│ 3 │ #include │ │2 days ago Stefan ^3b4a655│ 4 │ │ │ │ 5 │ int main() { │ │3 hours ago Stefan a2c365ad│ 6 │ int a = 1; │ │ │ 7 │ int b = 2; │ │2 days ago Stefan ^3b4a655│ 8 │ │ │2 days ago Stefan a0bd6d8c│ 9 │ │ │ │ 10 │ return a+b; │ │2 days ago Stefan ^3b4a655│ 11 │ } │ └────────────────────────────────────────────────────────────────┘ ################################################################################ ┏━╸╻╺┳╸ ┏━╸┏━┓┏━╸┏━┓ ┃╺┓┃ ┃ ┃╺┓┣┳┛┣╸ ┣━┛ ┗━┛╹ ╹ ┗━┛╹┗╸┗━╸╹ Powerful tool to search for code snippets - $ git grep "" - -A , -B , -C - --show-function/-p - --function-context/-W ################################################################################ ┏━╸╻╺┳╸ ┏┓ ╻┏━┓┏━╸┏━╸╺┳╸ ┃╺┓┃ ┃ ┣┻┓┃┗━┓┣╸ ┃ ┃ ┗━┛╹ ╹ ┗━┛╹┗━┛┗━╸┗━╸ ╹ Binary search to find commit that introduced a bug. ┌──────────────────────────────────────────┐ │$ git bisect start │ │$ git bisect bad │ │$ git bisect good │ └──────────────────────────────────────────┘ ┌──────────────────────────────────────────┐ │$ git bisect start HEAD HEAD~10 -- │ │$ git bisect run make test │ │$ git bisect reset │ └──────────────────────────────────────────┘ ################################################################################ ┏━┓┏━┓╺┳╸┏━╸╻ ╻╻┏┓╻┏━╸ ┣━┛┣━┫ ┃ ┃ ┣━┫┃┃┗┫┃╺┓ ╹ ╹ ╹ ╹ ┗━╸╹ ╹╹╹ ╹┗━┛ - Revert already commited changes - Pick a range of commits from different branches - Turn a commit into a git-readable file ################################################################################ ┏━╸╻╺┳╸ ┏━┓┏━╸╻ ╻┏━╸┏━┓╺┳╸ ┃╺┓┃ ┃ ┣┳┛┣╸ ┃┏┛┣╸ ┣┳┛ ┃ ┗━┛╹ ╹ ╹┗╸┗━╸┗┛ ┗━╸╹┗╸ ╹ Revert commits via new commits - Should be used when the commits are already public - $ git revert .. ################################################################################ ┏━╸╻╺┳╸ ┏━╸╻ ╻┏━╸┏━┓┏━┓╻ ╻ ┏━┓╻┏━╸╻┏ ┃╺┓┃ ┃ ┃ ┣━┫┣╸ ┣┳┛┣┳┛┗┳┛╺━╸┣━┛┃┃ ┣┻┓ ┗━┛╹ ╹ ┗━╸╹ ╹┗━╸╹┗╸╹┗╸ ╹ ╹ ╹┗━╸╹ ╹ Specify commits and apply them onto your HEAD - $ git cherry-pick .. - $ git cherry-pick ..master - essentially the same as $ git rebase master - Useful if e.g. a hotfix has been pushed to a stable branch - Might need to clean such commits before merging ################################################################################ ┏━╸┏━┓┏━┓┏┳┓┏━┓╺┳╸ ┏━┓┏━┓╺┳╸┏━╸╻ ╻ ┏┓ ┏━┓┏━┓┏━┓╻ ╻ ╻ ┣╸ ┃ ┃┣┳┛┃┃┃┣━┫ ┃ ╺━╸┣━┛┣━┫ ┃ ┃ ┣━┫ ┃╺╋╸ ┣━┫┣━┛┣━┛┃ ┗┳┛ ╹ ┗━┛╹┗╸╹ ╹╹ ╹ ╹ ╹ ╹ ╹ ╹ ┗━╸╹ ╹ ┗━┛ ╹ ╹╹ ╹ ┗━╸ ╹ In certain situations it might be sensible to send commits per mail - $ git format-patch -1 - colleague does not need to checkout your branch - $ git apply ################################################################################ ┏┳┓┏━┓┏━┓┏━╸ ┏━┓┏┓╻╺┳┓ ┏┳┓┏━┓┏━┓┏━╸ ┃┃┃┃ ┃┣┳┛┣╸ ┣━┫┃┗┫ ┃┃ ┃┃┃┃ ┃┣┳┛┣╸ ╹ ╹┗━┛╹┗╸┗━╸ ╹ ╹╹ ╹╺┻┛ ╹ ╹┗━┛╹┗╸┗━╸ - git notes, - commit signing, - merge strategies, - git worktree, - refs, - git reflog, - porcelain commands and scripting, - the power of .gitconfig, - hooks on the server, - multiple remotes, - etc.