2
© 2018 Brent Laster@BrentCLaster
2
Advanced Git:
Functionality and Features
All Things Open 2019
Brent Laster
3
© 2018 Brent Laster@BrentCLaster
3
@BrentCLaster
About me
§ Director, R&D
§ Global trainer – training (Git, Jenkins, Gradle,
Gerriit, Continuous Pipelines)
§ Author -
§ OpenSource.com
§ Professional Git book
§ Jenkins 2 – Up and Running book
§ Continuous Integration vs. Continuous Delivery vs.
Continuous Deployment mini-book on Safari
§ https://www.linkedin.com/in/brentlaster
§ @BrentCLaster
4
© 2018 Brent Laster@BrentCLaster
4
@BrentCLaster
Book – Professional Git
§ Extensive Git reference, explanations, and
examples
§ First part for non-technical
§ Beginner and advanced reference
§ Hands-on labs
5
© 2018 Brent Laster@BrentCLaster
5
@BrentCLaster
Jenkins 2 Book
§ Jenkins 2 – Up and Running
§ Deployment pipeline automation as code
§ “It’s an ideal book for those who are new to
CI/CD, as well as those who have been
using Jenkins for many years. This book will
help you discover and rediscover Jenkins.”
By Kohsuke Kawaguchi, Creator of Jenkins
6
© 2018 Brent Laster@BrentCLaster
6
@BrentCLaster
Agenda
§ Core concepts refresh
§ Merging and Rebasing
§ Stash
§ Reset and Revert
§ Rerere
§ Bisect
§ Worktrees
§ Subtrees
§ Interactive Rebase
§ Notes
§ Grep
7
© 2018 Brent Laster@BrentCLaster
Check Out
Commit
C
h
e
c
k
o
u
t
C
o
m
m
i
t
Clone
Remote
Repository
Local
Environment
Central
Server
Local
Machine
Centralized Version Control Model Distributed Version Control Model
Centralized vs. Distributed VCS
8
© 2018 Brent Laster@BrentCLaster
8
@BrentCLaster
Git in One Picture
Staging Area
Remote Repository
Local Repository
Working Directory
P
u
l
l
Dev
Prod
Public
Test
C
h
e
c
k
o
u
t
Server
Add
Commit
Push Clone
Local Machine
F
e
t
c
h
9
© 2018 Brent Laster@BrentCLaster
9
@BrentCLaster
Git Granularity (What is a unit?)
§ In traditional source control, the unit of granularity is usually
a file
§ In Git, the unit of granularity is usually a tree
dir: proj1
file1.java
file2.java
Working directory
file1.java
CVS
GitCommit
file1.java
Delta
Commit
Snapshot
10
© 2018 Brent Laster@BrentCLaster
10
@BrentCLaster
Merging: What is a Fast-forward?
§ Assume you have three branches as below
§ You want to merge hotfix into master (so master will have
your hotfix for future development)
$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast Forward
README | 1-
1 files changed, 0 insertions(+) 1 deletions (-)
About “Fast Forward” – because commit pointed to by branch merged was
directly “upstream” of the current commit, Git moves the pointer forward
(Both branches were in the same line of development, so the net result is that
master and hotfix point to the same commit)
C2
C3
C0 C1 C4
feature
hotfix
11
© 2018 Brent Laster@BrentCLaster
11
@BrentCLaster
Merging: What is a 3-way Merge?
§ Assume branching scenario below
§ master and feature branches have both diverged (changed) since their last common
ancestor (commit/snapshot)
§ Intent is to change to master and merge in feature
§ Current commit on target branch isn’t a direct ancestor of current commit on branch
you’re merging in (i.e. C4 isn’t on the same line of development as C5)
§ Git does 3-way merge using common ancestor
§ Instead of just moving branch pointer forward, Git creates a new snapshot and a new
commit that points to it called a “merge commit”
$ git checkout master
$ git merge feature
C2
C3
C4
C5
feature
C0 C1
Common
Ancestor
Branch Tip
Branch Tip
master
12
© 2018 Brent Laster@BrentCLaster
12
@BrentCLaster
Merging: What is a Rebase?
§ Rebase – take all of the changes that were committed on one branch and replay them on
another one.
§ Concepts in simple syntax (git rebase branch2 [branch1]):
§ Move branchpoint of branch (carrying along all commits) to be off of a different commit (new base)
§ Current branch (or branch1 if supplied) is one having its branchpoint moved
§ Branch2 (or commit) provided as first/only argument is the new branchpoint
§ In simple case, think of it as “pick up branch1 entirely and move its branchpoint to be after the tip of branch2)”
§ Process:
§ Goes to the common ancestor of the two branches (the one you are on and the one you are rebasing onto)
§ Gets the diff introduced by each commit of the branch you are on, saving them to temporary files
§ Applies each change in turn
§ Moves the branch to the new rebase point
$ git checkout feature
$ git rebase master
C3
C4
C5
C0
Common
Ancestor
C2
feature
C1
C3’ C5’
C2
master
13
© 2018 Brent Laster@BrentCLaster
13
@BrentCLaster
Command: Git Stash
§ Purpose -- allow you to keep a backup copy of your work that
hasn’t been committed yet
§ Use case - you want to switch branches but don’t want to
lose work that hasn’t been committed; you want to save
something you’ve tried and may want to come back to
§ Syntax:
14
© 2018 Brent Laster@BrentCLaster
14
@BrentCLaster
Stash
Staging Area
Staging Area
Local Repository
Working Directory
stash@{0}
Staging
Area *
Working
Directory *
stash@{1}
Staging
Area **
Working
Directory
**#
stash@{0}
Staging
Area ***
stash@{2}
******
******
stash@{1}
stash@{0}
stash@{0}stash@{1}
stash@{1}stash@{2}
“cool feature”
Working
Directory
***
> git stash> git stash -u
#
> git stash save “cool feature”> git stash apply stash@{1}$ git stash pop stash@{2}
15
© 2018 Brent Laster@BrentCLaster
15
@BrentCLaster
Command: Git Reset
§ Purpose -- allow you to “roll back” so that your branch points
at a previous commit ; optionally also update staging area
and working directory to that commit
§ Use case - you want to update your local environment back to
a previous point in time; you want to overwrite or a local
change you’ve made
§ Syntax:
§ Warning: --hard overwrites everything
16
© 2018 Brent Laster@BrentCLaster
16
@BrentCLaster
Command: Git Revert
§ Purpose -- allow you to “undo” by adding a new change that
cancels out effects of previous one
§ Use case - you want to cancel out a previous change but not
roll things back
§ Syntax:
§ Note: The net result of using this command vs. reset can be
the same. If so, and content that is being reset/revert has
been pushed such that others may be consuming it,
preference is for revert.
17
© 2018 Brent Laster@BrentCLaster
17
@BrentCLaster
Local Repository
Reset and Revert
git reset --hard 87ba8bc
git reset current~1 [--mixed]
git revert HEAD
Line 1
Staging Area
Working Directory
XYZ
ABC
Line 1
87ba8bc 43bd3ef d21be2c
Line 1
Line 2
Line 3
c1c8bd4
Line 1
Line 2
Line 1
Line 2
Line 1Line 1 Line 1
Line 2
tag: current
Line 1
Line 2
18
© 2018 Brent Laster@BrentCLaster
18
@BrentCLaster
Command: Git Rerere (Reuse Recorded
Resolution)
§ Purpose -- allows recording of how you solve a merge
situation and then can automatically resolve the same
situation in the same way if needed later
§ Use case - trial and repeated merges; merging newer versions
of a branch with the same conflicts into a newer one
periodically; resolve conflicts after reset or revert; applicable
to any repeated merge case: rebase, merge
§ Syntax:
§ Note: This is a “state” command. Enabled by turning on a
state in Git, rather than just running a command
§ Enabled via git config --global rerere.enabled 1
» Then runs automatically
§ Invoked directly via git rerere for related commands or options
19
© 2018 Brent Laster@BrentCLaster
19Local Repository
feature
Staging Area
File B
Working Directory
File C
File A
File B
master
File A
File C
File B
File A
File C
File BFile B
File B
<<>>
File BFile A File CFile BFile A File C
rr-cache
File A File C
File B
<<>>
preimage postimage
File B
Git Rerere 1
20
© 2018 Brent Laster@BrentCLaster
20Local Repository
feature
Staging Area
File B
Working Directory
File C
File A
File B
master
File A
File C
File B
File A
File C
File BFile B
File B
<<>>
File BFile A File CFile BFile A File C
rr-cache
File A File C
File B
<<>>
preimage postimage
File B
Git Rerere 2
21
© 2018 Brent Laster@BrentCLaster
21
@BrentCLaster
Command: Bisect
§ Purpose - Use “automated” binary search through Git’s history to find a
specific commit that first introduced a problem (i.e. “first bad commit”)
§ Use case - Quickly locate the commit in Git’s history that introduced a bug
§ Syntax:
22
© 2018 Brent Laster@BrentCLaster
22
@BrentCLaster
Git Bisect
§ Use “automated” binary search to find change that first introduced a bug (i.e.
“first bad commit”)
§ Initiate with git bisect start
§ Can pass range to start option to identify bad and good revisions – i.e.
git bisect start HEAD HEAD~10
§ Identify first “bad” commit, usually current one via git bisect bad
§ Identify a “good” (functioning) commit via git bisect good
§ From there, git will do a binary search and pick a “middle” commit to checkout.
§ Try the checked out version and indicate git bisect good or git bisect bad depending on
whether it works or not.
§ Process repeats until git can identify “first bad” commit/revision.
§ Can grab previous good revision by specifying “first bad”^
§ Can update, create new branch, rebase, etc. to isolate good revisions.
§ Other useful options to git bisect: log, visualize, reset, skip, run
23
© 2018 Brent Laster@BrentCLaster
23
@BrentCLaster
LOCAL REPOSITORY
Version 1Version 1
Bisect
§ checkout latest version
§ try code
§ git bisect start
§ git bisect bad
§ checkout earlier version ( user checks out)
§ try code
§ git bisect good (bisect checks out version 5)
§ try code
§ git bisect good (bisect checks out version 7)
§ try code
§ git bisect bad (bisect checks out version 6)
§ try code
§ git bisect bad (git reports version 6 as the first bad
commit)
Version 3
Version 4
Version 5
Version 6
Version 7
Version 8
Version 9
Version 10Version 10
Version 5
Version 2
Version 7
Version 6
FIRST BAD COMMIT
WORKING DIRECTORY
24
© 2018 Brent Laster@BrentCLaster
24
@BrentCLaster
Background: Switching between Branches
Command: git checkout <branch>
git checkout master
§ Does three things
§ Moves HEAD pointer back to <branch>
§ Reverts files in working directory to snapshot
pointed to by <branch>
§ Updates indicators
git checkout testing
git checkout master
git checkout testing
§ git branch
Local Repository
Working Directory
*
*
87ba8bc 43bd3ef d21be2c c1c8bd4
master
testing
25
© 2018 Brent Laster@BrentCLaster
25
@BrentCLaster
Worktrees - syntax and usage
§ Syntax
§ git worktree add [-f] [--detach] [-b <new-branch>] <path> [<branch>]
§ git worktree list [--porcelain]
§ git worktree prune [-n] [-v] [--expire <expire>]
§ Subcommands
§ Add - create a separate working tree for specified branch
» has checked out copy of the branch
» if no branch specified, uses same name as temp area
§ List - lists out current set of working trees active for this repo
» porcelain - consistent and backwards-compatible format
§ Prune - removes worktree information from the .git area
» only applies after worktree directory tree has been removed
26
© 2018 Brent Laster@BrentCLaster
26
@BrentCLaster
Command: Worktree
§ Purpose - Allows multiple, separate Working Areas attached to one
Local Repository
§ Use case - Simultaneous development in multiple branches
§ Syntax
§ Notes
§ “Traditional” working directory is called the main working tree; Any new
trees you create with this command are called linked working trees
§ Information about working trees is stored in the .git area (assuming .git
default GIT_DIR is used)
§ Working tree information is stored in .git/worktrees/<name of worktree>.
27
© 2018 Brent Laster@BrentCLaster
27
@BrentCLaster
Worktree
§ git worktree add -b exp tree1
§ git worktree add -b prod tree2
Remote Repository
Main Working Tree
Server
Add
Commit
Push Pull
Staging Area
Local Repository
Working Directory
(master)
Local Machine
worktrees/
tree1
gitdir
HEAD
etc.
tree1
Linked Working Tree
Staging Area
Working Directory
(exp)
gitdir
HEAD
etc.
tree2
Linked Working Tree
Staging Area
Working Directory
(prod)
tree2
28
© 2018 Brent Laster@BrentCLaster
28
@BrentCLaster
Command: Subtree
§ Purpose - Allows including a copy of a separate repository
with your current repository
§ Use case - include a copy of a Git repository for one or more
dependencies along with the original repository for a project
§ Syntax
§ Notes
§ No links like a submodule - just a copy in a subdirectory
§ Advantage - no links to maintain
§ Disadvantage - extra content to carry around with your project
git subtree add -P <prefix> <commit>
git subtree add -P <prefix> <repository> <ref>
git subtree pull -P <prefix> <repository> <ref>
git subtree push -P <prefix> <repository> <ref>
git subtree merge -P <prefix> <commit>
git subtree split -P <prefix> [OPTIONS] [<commit>]
29
© 2018 Brent Laster@BrentCLaster
29
@BrentCLaster
Subtrees - overall view
30
© 2018 Brent Laster@BrentCLaster
30
@BrentCLaster
Subtrees - adding a project as a subtree
§ Simplest form, specify: prefix,
remote path to repository,
branch (optional)
§ Suppose we clone down a
project - myproject
§ And, on the remote side, we
have another project, subproj.
§ Now, we can add subproj as a
subtree of myproject (--prefix
subproject).
§ Subtree now shows subproject
in structure and history
31
© 2018 Brent Laster@BrentCLaster
31
@BrentCLaster
Command: (Interactive) Rebase
§ Purpose - allows you to run operations against commits in the
git history
§ Use case - you need to make some kind of modification to
one or more commits in the repository (rewrite history)
§ Syntax
§ Notes - creates an interactive script/batch file to modify
commits
§ Cautions - don’t use this on anything already pushed
32
© 2018 Brent Laster@BrentCLaster
32
@BrentCLaster
Interactive Rebase
§ Choose set of
commits
§ Initiate
interactive
rebase
§ Git presents
initial script
§ Modify
commands (save
and exit)
§ Act on prompts
§ Commits are
updated
33
© 2018 Brent Laster@BrentCLaster
33
@BrentCLaster
Command: Notes
§ Purpose - Add additional information to objects in the Git repository or
look at such information
§ Use case - At some point after making a commit, you may decide that
there are additional comments or other non-code information that you’d
like to add with the commit - without changing the commit itself.
§ Syntax
git notes [list [<object>]]
git notes add [-f] [--allow-empty] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]
git notes copy [-f] ( --stdin | <from-object> <to-object> )
git notes append [--allow-empty] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]
git notes edit [--allow-empty] [<object>]
git notes show [<object>]
git notes merge [-v | -q] [-s <strategy> ] <notes-ref>
git notes merge --commit [-v | -q]
git notes merge --abort [-v | -q]
git notes remove [--ignore-missing] [--stdin] [<object>…]
git notes prune [-n | -v]
git notes get-ref
34
© 2018 Brent Laster@BrentCLaster
34
@BrentCLaster
Notes
§ Create a note
§ Create a note in a custom
namespace (add --ref)
§ View a note (for a specific
revision)
§ List notes in log
35
© 2018 Brent Laster@BrentCLaster
35
@BrentCLaster
Command: grep
§ Purpose - provides a convenient (and probably familiar) way to search for regular
expressions in your local Git environment.
§ Use case - self-explanatory
§ Syntax
git grep [-a | --text] [-I] [--textconv] [-i | --ignore-case] [-w | --word-regexp]
[-v | --invert-match] [-h|-H] [--full-name]
[-E | --extended-regexp] [-G | --basic-regexp]
[-P | --perl-regexp]
[-F | --fixed-strings] [-n | --line-number]
[-l | --files-with-matches] [-L | --files-without-match]
[(-O | --open-files-in-pager) [<pager>]]
[-z | --null]
[-c | --count] [--all-match] [-q | --quiet]
[--max-depth <depth>] [--color[=<when>] | --no-color]
[--break] [--heading] [-p | --show-function]
[-A <post-context>] [-B <pre-context>] [-C <context>]
[-W | --function-context]
[--threads <num>]
[-f <file>] [-e] <pattern>
[--and|--or|--not|(|)|-e <pattern>…]
[ [--[no-]exclude-standard] [--cached | --no-index | --untracked] | <tree>…]
[--] [<pathspec>…]
§ Notes
§ Several options are similar to OS grep options
36
© 2018 Brent Laster@BrentCLaster
36
@BrentCLaster
grep
§ Default behavior - search for all instances of an expression across all tracked files in working directory
§ Search for all instances off expression “database” across all java files (note use of -- )
§ -p option tells Git to try and show header of method or function where search target was found
§ --break - make output easier to read
§ --heading - prints filename above output
§ boolean operators
§ search in staging area
§ search in specific commit(s)
37
© 2018 Brent Laster@BrentCLaster
37
That’s all - thanks!