Software Engineering / Tools / Git Source Control Management (SCM)¶
Git is a source control management tool that helps to keep track of changes made to a codebase.
This page provides an overview of some useful concepts and commands.
- Software Engineering / Tools / Git Source Control Management (SCM)
 - Installation
 - Installation on Ubuntu 16.04
 - Git Branching Models
 - GitFlow
 - Trunk-Based Development
 - Initialisation
 - Clone a repository
 - Create a new repository
 - Remote management
 - Add a Git remote
 - Update the Git remote
 - Retrieving changes
 - Fetch changes
 - Merge changes
 - Pull changes
 - Pull with Rebase
 - Rebase
 - Saving changes
 - Stashing
 - Staging
 - Commiting
 - Commiting without any changes
 - Modifying changes
 - Adding a file to a previous commit
 - Squash commit
 - Uncommit last commit
 - Reverting a commit
 - Submitting changes
 - Pushing
 - Force Pushing
 - Assessing changes
 - View all current changes
 - View commit history
 - View difference between commits
 - Viewing repository information
 - View the Git configuration
 - Check which branch you're on
 - See all remotes
 - Checking which 
.gitignoreis ignoring a file - Repository adminstration
 - Creating a new branch from an existing one
 - Deleting a local branch
 - Deleting a remote branch
 - Deleting local remote branches that have been deleted remotely
 
Installation¶
Installation on Ubuntu 16.04¶
sudo add-apt-repository ppa:git-core/ppa;
sudo apt-get update;
sudo apt-get install git;
Git Branching Models¶
GitFlow¶
GitFlow is a branching model for Git created by Vincent Driessen.
- Generally seen in more traditional enterprise software development where process and stability is prioritised over agility (think Waterfall)
 - 5 types of branches:
 masterbranchhotfixbranchreleasebranchdevelopbranch- 
featurebranch 
Trunk-Based Development¶
Trunk-Based Development is a branching model where developers commit and push to the master branch continuously.
- Generally seen in more modern software development teams where process and stability is deprioritised over business agility (think Agile)
 - Typically seen with Continuous Delivery (CD) pipelines
 - Usually requires the following to successfully implement/reap full benefits:
 - Agile Software Development Lifecycle (SDLC)
 - Service-oriented architectures (SOA)
 - Observability instrumentation
 - 
Feature toggling
 
Initialisation¶
Clone a repository¶
Why
- I would like to make a local copy of code from a public repository I found online.
 
# for http-based
git clone https://zephinzer@github.com/zephinzer/blog.joeir.net
# for ssh-based
git clone ssh://git@github.com/zephinzer/blog.joeir.net
Create a new repository¶
Why
- I would like to initialise a new Git repository on my computer.
 
git init
Remote management¶
Add a Git remote¶
Why
- I would like to add a new remote named 
originto my repository. 
git remote add origin ssh://git@github.com/zephinzer/blog.joeir.net
Update the Git remote¶
Why
- I would like to update the URL for my remote named 
originin my repository. 
git remote set-url origin ssh://git@github.com/zephinzer/blog.joeir.net
Retrieving changes¶
Fetch changes¶
Fetching retrieves the changes but does not merge the changes with your local copy.
Why
I would like to get updates from the remote but I don't want to update my code yet.
git fetch
Merge changes¶
Merging takes the remote changes that have been fetched from the remote and merges them with your local copy.
Why
I have reviewed the changes I retrieved from the remote and I want to update my local code to match the remote's copy now.
git merge HEAD
Pull changes¶
Pulling basically does a fetch and merge.
Why
I would like to update my code so that it is the same as the remote's.
git pull
Pull with Rebase¶
Pulling with rebase does a fetch, but before merging in the remote changes, it rolls back to a state before all remote changes were made, applies the remote changes, and then applies your local changes.
Why
I would like to update my code by placing whatever's from the remote before my current changes so that it is the same as the remote's and I don't have a merge commit.
git pull -r
Rebase¶
Why
- I would like to pull in changes from another branch that's available locally and place those changes before the changes I've committed.
 
# assuming we are on branch feature_x pulling in updates from master
git rebase master
Saving changes¶
Stashing¶
Why
- I would like to temporarily store my unstaged changes so that I can pull in the latest updates from the remote.
 
# put all unstaged changes into a stash
git stash
# checking stashed changes
git stash list
# popping the last stashed change
git stash pop
Staging¶
Why
- I would like to add file(s) that will be 'saved' during a commit.
 
# to stage all changes, run this from project root
git add .
# to stage only one file
git add ./path/to/changed_file
Commiting¶
Why
- I would like to save my changes to my local Git repository.
 
git commit -m 'some message'
Commiting without any changes¶
Why
- I would like to add a commit to my local repository without adding any files
 - I would like to have a commit that can trigger a pipeline in the remote source control
 
git commit --allow-empty 'some message'
Modifying changes¶
Adding a file to a previous commit¶
Why
- I forgot to run 
git addon a file that should be in the previous commit. 
# stage the missing file first
git add ./path/to/missed/file;
# this will add the staged file to the previous commit
git commit --amend
Squash commit¶
Why
- I have made 5 commits and I would like to compress them into a single commit so my Git history is cleaner.
 
# indicate `p` or `pick` for the head commit, and `s` or `squash` for the rest
git rebase -i HEAD~5
Squashing till origin/master/HEAD¶
Why
- I have made X number of commits to my branch and want to squash/rebase my commits within my branch so that a rebase with master will be cleaner
 
git rebase -i HEAD~$(git log --oneline master..HEAD | wc -l);
Uncommit last commit¶
Why
- I would like to reverse the last commit but leave changes I made intact
 
# this will leave the committed files as staged
git reset --soft HEAD^
# this will also unstage all changes
git reset HEAD^
Reverting a commit¶
Why
- I would like to create a commit that reverses the changes in a certain commit with hash 
${COMMIT_HASH} 
# use `git log` to find the commit hash of the commit you wish to undo the effects of
git revert ${COMMIT_HASH}
Submitting changes¶
Pushing¶
Why
- I would like push all committed changes from my computer to the remote
 
git push
Force Pushing¶
Why
- I have modified a commit locally and am unable to push normally to the remote since I rewrote history (WARNING: this will erase any changes others may have made between when the original commit was made, and your current commits)
 
git push -f
Assessing changes¶
View all current changes¶
Why
- I would like to see what files have been staged
 
git status
View commit history¶
Why
- I want to do an interactive rebase (squashing) and I would like to see which commit I should rebase up till
 - I want to see what changes have been made by other team members/developers
 
# interactive browsing of git commits
git log
# output only the last 5 logs
git log -n 5
View difference between commits¶
Why
- I would like to check out what changes have been made between two commits
 
# view file changes from HEAD to ${COMMIT_HASH}
git diff HEAD ${COMMIT_HASH}
Viewing repository information¶
View the Git configuration¶
Why
- I would like to see who am I committing code as
 
git config -l
Check which branch you're on¶
Why
- I would like to confirm which branch I am on
 
git branch
See all remotes¶
Why
- I would like to see which remotes I am pushing to
 
git remote -v
Checking which .gitignore is ignoring a file¶
Why
- I would like to know which 
.gitignoreis causing a file to be ignored without any obvious reason 
cd `./path/to`;
git check-ignore -v *;
Repository adminstration¶
Creating a new branch from an existing one¶
Why
- I would like to create a new branch based on the current one I'm on
 
git checkout $SOURCE_BRANCH_SLUG;
git checkout -b $NEW_BRANCH_SLUG;
Deleting a local branch¶
git branch -D $BRANCH_SLUG;
Deleting a remote branch¶
git push origin --delete $BRANCH_SLUG;
Deleting local remote branches that have been deleted remotely¶
git remote update origin --prune;