Git Best Practices
Solutions to increase your team-based development
This video course is not a full tutorial on Git!
... does not cover all commands & features
... illustrates important concepts & processes
Core concepts and techniques for your Ameriprise work.
Git Best Practices
... increases your productivity as a developer!
Video Tutorials
Git Best Practices
Workshop + Video Tutorials
Git Squashing
Git Feature Branches
GitFlow Development
Git Forks
Git Concepts
Git Rebasing
Git Pull Requests
Git Commits
Git Code Reviews
Customizing Git
Git Health Checks
Git Rules for Developers
Guidelines
Git Concepts
.... core ideas & foundation
Git Concepts
Quick Overview
What is Git ?
SCM: Source Code Management
VCS: Version Control Software
Git
Repository
Changed Files
Commits
Branches
aka timelines
aka snapshots
Git Branches
Recent Commit
Oldest Commit
Git Branches:
Recent Commit
Oldest Commit
Git Commits
Recent Commit
Oldest Commit
Git Commit History
Git is a distributed SCM
Can be easily cloned and used on multiple machines...
Thomas
Harry
clone
Git in the Cloud
Using a centralized cloud SaaS
Github
Git vs GitHub
Github
Using a centralized cloud SaaS
Easy Collaboration
Open-source VCS
Developer Tooling
Git
Git as a distributed SCM
Sharing snapshots and code... using centralized cloud SaaS.
clone
clone
Github
push
pull
Git as a distributed SCM
Sharing snapshots and code... using centralized cloud SaaS.
Github
Git Rules for Developers
Git Forks
.... enable external contributions
Git Forks
When the cloud repository has strict control and is considered read-only.
When the cloud repository refuses to allow feature branches.
Repo ProjectX
`origin`
Harry
Thomas
push
pull
Repo ProjectX
Prevent
Reject Force Push
Degreed Pathways Team
Team X
Team X
Open Source Community
Repo ProjectX
Enterprise Scaling Considerations
Push to feature branches ONLY!
`upstream`
Git is a distributed VCS
clone
Repo ProjectX
fork
`origin`
Repo ProjectX
`origin`
`upstream`
Using a Fork: Merging Changes to `upstream`
fork
clone
pull
push
pull
merge via Pull Request
https://github.com/degreed/fe-code-challenge
<your own repo>
Local Development Setup
`origin`
`upstream`
Using a Fork: Merging Changes to `upstream`
fork
clone
(1)
pull
(2)
push
https://github.com/degreed/FE-Coding-Challenges-Starter
<your own repo>
Local Development Setup
(3)
create Pull Request
push
pull
Harry
`origin`
GitFlow Development
.... a team process
GitFlow Development
Git Tracks Changes
Git Branches
Development using Git
Trunk-Based
Feature-Based
Development
Development
Using GitFlow
GitFlow is Feature-based Development
+
GitFlow Branching Model
GitFlow Branching Model
GitFlow Branching Model
GitFlow Branching Model
GitFlow Branching Model
GitFlow Branching Model
99% of all works starts from the`develop` branch
All work is merged back into the the`develop` branch
Developer Work
in Feature Branches
Git Feature Branches
.... where you 'do' your work!
Git Feature Branches
What is a Feature Branch?
A feature branch is a branch created from the `develop` branch for a specific change, fix, or enhancement.
Usually this is a branch that is used for 1-2 weeks... but may exist longer.
myFeature1
99% of all works starts from the`develop` branch
All work is merged back into the the`develop` branch
Feature Branch
for
Developer Work
GitFlow: `develop` branch
The develop branch is special:
<author>/<work-type>/<JIRA-issue | title>
Branch Naming Conventions
Use the following convention:
Sample branch names:
feature/team-hp/update-business-rules
feature/mentoring/mentees
feature/launch-darkly/mentoring/mentors
bugfix/45
hotfix/100
GitFlow
Grouping Branches
feature/1347
bugfix/45
Use 'forward slash' in the branch name to group branches by type:
GitFlow: Feature branches
To create a Feature branch:
Developer Work
in Feature Branches
HEAD
GitFlow: Feature branches
HEAD
GitFlow: Feature branches
Team Development
Project A
Project B
Project C
mono-repo
GitFlow + Feature Branches
Git Commits
.... concepts, conventions
Git Commits
A single (1) Git Commit
Series of Git Commits
Recent Commit
Oldest Commit
A Git commit is snapshot of the project at that time.
master
finish/jumpstart
finish/rxjs
Each Git branch has its own commit stack....
These branch commits are independent!
git checkout -b <branch>
Creates a new branch based on snapshot of current branch stack...
master
finish/jumpstart
finish/rxjs
A branch can be created based upon commits from another branch!
Recent
Oldest
Current Branch: finish/rxjs
HEAD
Each commit is unique. The SHA1 is a hash value based on ALL the following information:
For all local changed or deleted files, we can capture a project snapshot using:
git commit -am "(jumpstart) lab 4: Sharing services with Context API"
Note: this ^ commit is only saved in the local repository
... other Git commands must be used to push to the cloud repository.
For all local changes, we can capture a project snapshot using:
git add .;
git commit -am "(jumpstart) lab 4: Sharing services with Context API";
`git add .` will add all new files to staging...
We push a commit to `origin` to:
# 1st time you push your local changes
# connect and track that remote branch with the local
git push -u origin <current-branch-name>
# If Git history has been changed AND
# you are pushing to your OWN branch
git push -f
push
origin
For details on `log`, see the appendix videos for "Customizing Git"
Format Rules for Git Commit
Why do we have conventions and rules for Git commit messages ?
Format Rules for Git Commit
Format Rules for Git Commit
Git Commit Guidelines
Squashing Git Commits
Git Commit Squashing
Why Git Squashing?
Series of Git Commits
Recent Commit
Oldest Commit
Reduce a sequence of commits into a SINGLE commit.
Reduce a sequence of commits into a SINGLE commit.
A single (1) Git Commit
## Interactively rebase the 6 most recent commits
git rebase -i HEAD~6
## Or specify the SHA you want to start with...
git rebase --interactive [commit-hash]
oldest commit
newest commit
Unlike log outputs, rebase ordering is reversed
(1) reword
(2) squash
Use the rebase Commands to reword and squash:
Or better yet:
Squashing allows developers to be sloppy with commits WHILE working.
Squashing provides the opportunity to reword the resulting commit with details in message <body>
Git Rebasing
.... concepts, commands, and secrets
Git Branch Rebasing
Why is Rebasing important ?
Rebasing ensures your feature changes are based upon up-to-date base branch code.
A feature branch is created based upon commits from another branch!
master
finish/jumpstart
finish/rxjs
git rebase <branch>
Can use the terminal command:
HEAD
HEAD
Add two (2) commits to `master`
HEAD
Why did the two (2) new commits in `master` not show in the log for `finish/rxjs`?
Rebase Scenario:
HEAD
Need to update the base commits... REBASE
Answer:
develop
git pull --rebase origin <branchname>
git pull origin <branchname>
Never Pull without Rebase!
Rebase places the remote commit history under your local commit changes and the newer history!
How does Rebasing work ?
A Rebasing Scenario:
The `finish/nx` has a new commit `test(nx): lab 4b - Add tests`
The `feature/2020` branch needs to be rebased with the recently updated `finish/nx` branch.
Your `feature/2020` branch has 4 new commits on top of the base branch `finish/nx`
A Rebasing Scenario:
## rebase on `finish/nx`
git rebase finish/nx
Your `feature/2020` branch has 4 new commits on top of the base branch `finish/nx`
A Rebasing Scenario:
Step 1: Temporarily remove your commits
A Rebasing Scenario:
Step 1: Temporarily remove your commits
Step 2: Update with latest `finish/nx` branch commits
A Rebasing Scenario:
Step 3: Restore oldest commit first... resolve conflicts if any
A Rebasing Scenario:
Step 3: Restore oldest commit first... resolve conflicts if any
Step 4: Restore remain commits (oldest to newest)...resolve conflicts if any.
A Rebasing Scenario:
Step 3: Restore oldest commit first... resolve conflicts if any
Step 4: Restore remain commits (oldest to newest)...resolve conflicts if any.
A Rebasing Scenario:
Step 3: Restore oldest commit first... resolve conflicts if any
Step 4: Restore remain commits (oldest to newest)...resolve conflicts if any.
NEVER use `git merge`
Note:
## Never do this
## this pollutes the target commit history
git merge feat/2020 develop
## Always use rebase and PRs w/ fast-forward merges
## to append feature changes to `develop`
git rebase `develop`
Flat, linear commit histories enable automated change log generation
`git rebase` Golden Rule
NEVER use `git rebase` on public branches:
ALWAYS use `git rebase` on feature branches
Extra: Never force-push to public branches!
`git rebase` Golden Rule
Using `git rebase` may REQUIRE a force-push to your feature branch:
## Rebase changed the commit history
## Need to force-push changed history
git push -f origin <branch-name>
Never force-push to public branches!
Squash your commits before rebasing
What is secret to Rebasing ?
Developers struggle with rebasing because of commit conflicts!
The Rebase Onto Git Command
Git Rebasing-Onto
git rebase --onto
Using:
git checkout -b feature/1
git checkout -b feature/2
Each branch should have its own independent changes
How do I fix a branch that has the WRONG base branch?
git checkout feature/2
git rebase --onto <desired-branch> <wrong-branch>
Use `git rebase --onto`
git checkout feature/2
git rebase --onto develop feature/1
Git Pull Requests
.... concepts, commands, and clarity
Git Pull Request
Pull Requests are features available ONLY within cloud services like GitHub, BitBucket, etc.
A Pull Request is a user-friendly web interface for reviewing & discussing proposed changes before merging those changes into the target branch.
A process that requests changed code to be merged from one branch into another branch.
A request for someone to pull the changes into the target destination branch.
....can be used between Forks
Pull Requests cannot be created for a local-only branch.
The branch must be pushed to the remote `origin` first.
git pull --rebase origin develop
git push -f origin [feature-branch]
git rebase -i HEAD~[n]
Your Pull Request description is very important.
Your description details WHY the PR has been prepared!
The PR title will be prefilled with your last commit message
Limit reviewers to 1 or 2.
Avoid always use the same reviewer(s)
Animated GIFs are AWESOME!
What happens if the Pull Request does NOT conform
to our rules and conventions ?
If PR with a WIP label:
Before code review, if PR does not conform:
The more you make your reviewers struggle, the greater the risk is that your Pull Request will be rejected.
Git Code Reviews
.... etiquette, collaboration, and change management
Git Code Reviews
Git Code Reviews
Great
Code reviews are a great opportunity to share and collaborate.
Code reviews are a based on respect and trust.
Code reviews minimize regression issues.
Code reviews promote consistency and standards.
Git Code Reviews
Great
Based on following all Pull Request conventions and requirements.
Automated Prettier formatting
Up-to-date Rebasing
Automated tests for CI/CD Lint, Build, and Tests
Expectations
Code Review
Key expectations that radically improve the code review process:
Reasonable response time from reviewers
Reviewers should avoid subjective issues
Big issues should 1st be discussed offline; using a video call and pair programming.
Reviewers should avoid accusatory language
Reviewer Tips
Code Review
Communicate clearly and succinctly
Plan for one (1) review cycle
If your required changes are resolved,
avoid adding-on more issues.
Avoid commenting on PRs unless your are an assigned reviewer or the Tech Lead.
architecture, separation of concerns, tests, separation of logic, etc.
Look for big issues:
Reviewer Tips
Code Review
Communicate clearly and succinctly
Provide feedback if your review will be delayed > 1 day.
Comment on at least 1 item that you like ...explain why.
Avoid subjective issues
Avoid accusatory language
Consider providing code snippets for suggested improvements
Toxic Behavior
Code Review
Author Tips
Code Review
Communicate clearly and succinctly
Avoid arguing with the Reviewers
Learn to identify feedback that is required vs suggested.
Avoid using the same reviewer(s)
Code reviews give you a chance to show your skills and bragging!
Reviewers can find things you may have missed. This is good...
Git Health Check
Score Card
Git Health Check
How do you assess the health of your organization's software development?
Need Qualitative metrics on Git usage.
Answer:
It is often unclear how teams use Git productively.
Health Check
How do you assess the health of your IT organization?
Need Qualitative metrics on Software Development
Answer:
How organized is your team-based product development?
Impact of Git Health
Lower Delivery Costs
Increased ROI
Development Best Practices
Git: Clarity & Consistency
Lower Regressions,
Improved Sprint Results
Improved Collaboration
Health Check
Score Card
Total:
Code Organization
Are you using Nx ...........................................................................(+1)
Are you using a mono-repository .................................................(+1)
Are you using isolated repositories ..............................................(-1 )
Are you using monolithic app development ...............................(-1 )
Does repo have a clear, articulate README ................................(+1)
Do the repo libraries have README(s) .........................................(+1)
Are you using StoryBoard to test/demo UI components ..........(+1)
Does the organization have a shared UI component library ....(+1)
Code Builds
Are you using Prettier ....................................................................(+1)
Are you using Lint checks ..............................................................(+1)
Are you using unit tests + integration tests + e2e tests?............(+1)
Are you using Typescript or Java ..................................................(+1)
Are you using only ES5 for their development ...........................(-1 )
Are you auto-generating ChangeLogs? ........................................(+1)
Code Standards
Do you have a Guidelines for Team-based development ..........(+1)
Do you have Documented Coding Standards .............................(+1)
Using separation of business logic outside UI components ......(+1)
Subtotal:
Subtotal:
Subtotal:
Web Development Teams
Health Check
Score Card
Total:
Git Best Practices
GitFlow + Feature-Based Development
Do you use `develop` for the shared development branch ......(+1)
Are you using feature-branches ....................................................(+1)
Are you using repo cloud forks .......................................................(+1)
Are you commit histories flat and linear ......................................(+1)
Are you using commit message conventions ...............................(+1)
Do you reject force-push commits .................................................(+1)
Do you have protected branch access ...........................................(+1)
Do you have assigned code owners ...............................................(+1)
Do you require PRs and Code Reviews .........................................(+1)
Pull Requests
Are you using proper Pull Request conventions ..........................(+1)
Do the pull requests use status labels ..........................................(+1)
Using CI/CD checks on Lint, Build, and Tests ................................(+1)
Subtotal:
Subtotal:
Appendix Extras:
Customizing Git
Using Custom Aliases
Bash Commands for Git
Custom Bash Prompt
Shortcut commands to make Git life easier...
Use terminal window `git config` to configure global custom aliases:
# Alias to quick checkout
git config --global alias.co checkout
# Alias to rebase from origin/develop
git config --global alias.prd "!git pull --rebase origin develop"
# Alias to amend current commit with new + modified files
git config --global alias.amend "!git add . && git commit --amend --no-edit"
git config --global alias.[short-cmd] [full-cmd]
1
Shortcut commands to make Git life easier...
Use terminal window `git config` to configure global custom aliases:
# Alias to quick checkout
git config --global alias.co checkout
# Alias to rebase from origin/develop
git config --global alias.prd "!git pull --rebase origin develop"
# Alias to amend current commit with new + modified files
git config --global alias.amend "!git add . && git commit --amend --no-edit"
git co
git prd
git amend
new terminal commands
1
Shortcut command for Commit History
# Prettified Commit History
git config --global alias.plog 'log --color --graph --pretty=format:"%C(red)%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset" --abbrev-commit'
1
git plog
git plog
1
For those developers with Unix-based OS, you can use Bash commands to enhance your Git commands.
# Open hidden bash_profile in editor
code ~/.bash_profile
# Force OS to rescan the profile
source ~/.bash_profile
Bash Aliases
# @see https://haacked.com/archive/2014/07/28/github-flow-aliases/
alias irebase='git rebase -i HEAD~$@'
alias abort='git rebase --abort'
alias continue='git add . && git rebase --continue'
alias amend='git add . && git commit --amend --no-edit'
alias commit='git add . && git commit -m $@'
Add these super cool aliases to your bash profile:
2
For those developers with Unix-based OS, you can use Bash commands to enhance your Git commands.
# Open hidden bash_profile in editor
code ~/.bash_profile
# Force OS to rescan the profile
source ~/.bash_profile
Bash Functions
function branches() {
git branch --list --column
}
function rebase() {
if
$1
then
git pull --rebase origin $1
else
git pull --rebase origin develop
fi
}
Add these super cool functions to your bash profile:
2
Extend your command prompt to show Git information (when available):
# Open hidden bash_profile in editor
code ~/.bash_profile
Bash Functions
# Text color variables
txtReset=$(tput sgr0) # Reset
c_red=`tput setaf 1`
c_green=`tput setaf 2`
# Update command prompt to show `<cwd> [<git branch name>]`
PS1='\[${c_green}\]\W\[${txtReset}\] [\[$(branch_color)\]$(parse_git_branch)\[${txtReset}\]]: '
# Add functions for branch_color() and parse_git_branch()
Add these super cool functions to your bash profile:
3
Bash Functions
# Update command prompt to show `<cwd> [<git branch name>]`
PS1='\[${c_green}\]\W\[${txtReset}\] [\[$(branch_color)\]$(parse_git_branch)\[${txtReset}\]]: '
# Highlight branch name in `red` color if the repo contains uncommitted changes
branch_color ()
{
if git rev-parse --git-dir >/dev/null 2>&1
then
color=""
if git diff --quiet 2>/dev/null >&2
then
color="${c_green}"
else
color=${c_red}
fi
else
return 0
fi
echo -ne $color
}
# Determine branch name if CWD is part of a git repository
parse_git_branch ()
{
if git rev-parse --git-dir >/dev/null 2>&1
then
gitver=$(git branch 2>/dev/null| sed -n '/^\*/s/^\* //p')
else
return 0
fi
echo -e $gitver
}
Add these super cool functions to your bash profile:
3
Extend your command prompt to show Git information (when available):
# Force OS to rescan the profile
source ~/.bash_profile
# Update command prompt to show `<cwd> [<git branch name>]`
PS1='\[${c_green}\]\W\[${txtReset}\] [\[$(branch_color)\]$(parse_git_branch)\[${txtReset}\]]: '
3
Appendix Extras:
Git Time Machine
Log of all activity within the repository.
The reflog acts as a time machine enabling developers to easily go back in time.
# Show the timeline
git reflog
1
git reflog HEAD@{n}
1
git reflog develop@{one.week.ago}
means show the timeline 'n' moves/changes from HEAD
means show the timeline for 'develop' 1 week ago
git checkout 398c05b
Recall that
1
means checkout to a DETACHED (virtual branch) the project snapshot for "test(nx) Lab 4"