A Graceful Guide to Git
October 14, 2021
Overview
Basic Commands
Configuration
git config --global user.name <username>
- set usernamegit config --global user.email <email>
- set email
Initialising A Repo
git clone [https://github.com:ACCOUNT/REPO.git](https://github.com:ACCOUNT/REPO.git)
- clone repo from GitHubgit init -b main
- create repo locally in current working directory
Staging Changes
When working with git, there are 3 components to think about:
- Working directory (all your local files and folders)
- Staging area (all file changes tracked by git, but not yet saved by git)
- Git directory (all changes saved by git)
With this structure, git recognises the state of a file in the working directory as either: untracked
, unmodified
, modified
or staged
. When you add a file to your working directory, you use git to track them. When you modify a file, you use git to stage them. Once you have staged the changes you want to make, you use git to commit these stages. These commits may be used to look back in time at previous versions of your code (and lots more).
git add .
- stage all files (current directory)git add --all
- stage all files (current + sub directories)git add \_.py
- stage all files by wildcard (current directory)git add \*\*/\_.py
- stage all files by wildcard (current + sub directories)
Committing
git commit -m "<commit_message>"
- commit all staged changesgit commit --allow-empty -m "<commit_message>"
- commit an empty change
Viewing Git Information
git status
- show working directory and staging areagit log
- show commit history for CURRENT branchgit log --all
- show commit history for ALL branchesgit log --author="Author Name" --oneline
- show commit history for particular authorgit ls-files -s
- show which files have been stagedgit rev-parse HEAD
- view current commit hashgit shortlog -sn | head -3
- view top contributors for a repo
Intermediate Commands
Branching
Viewing branches:
git branch -a
- view all branches (local and remote)git cherry -v main <branch_name>
- view change in commit history between branches
Creating branches:
git branch <branch>
- create new branchgit checkout <branch>
- checkout new branchgit checkout -b <branch>
- create and checkout new branch
Deleting branches:
git branch -d <branch>
- delete branch on localgit push origin --delete <branch>
- delete branch on remotegit fetch -p
- pull updates from remote-tracking branches and prune remote branches if they have been deletedgit remote update origin --prune
- update local list of remote branches
It doesn't matter which branch you are on when staging changes, it only matters when these changes are committed (ie: stage files on whatever branch, but make sure to commit those changes on the desired branch).
Merging Changes
Create a feature branch to work on your code modifications. Once you are happy with the changes, you want to merge these back into the main branch.
git checkout <branch>
- make changes, stage files, commit stages
git checkout main
git merge <branch>
- resolve any conflicts, stage changes, commit stages
Setting an Upstream Branch
Setting an upstream (where a local branch tracks a remote branch) makes pushing/pulling easier and allows you to see any unsynced commits between the two.
git remote add origin [https://github.com:USER/PROJECT.git](https://github.com:USER/PROJECT.git)
- add remote branch for repo USER/PROJECTgit remote -v
- check remote branchesgit branch -u origin <local_branch>
- set upstream branchgit push -u origin <local_branch>
- set upstream branch when pushing changes (this is equivalent to above)
Create local branch to match remote branch:
git switch <remote_name>
Merge remote git repository into unrelated local git repository
git pull origin main --allow-unrelated-histories
Working Remotely
git push -u origin main
- push local changes to remote repo and set upstream branchgit push
- once you've set an upstream branch, you can use the following shorthandgit pull origin main
- pull remote changes into local repogit pull
- once you've set an upstream branch, you can use the following shorthand
Configuration:
git remote set-url origin git@github.com:<USERNAME>/<REPOSITORY>.git
- change remote URL to use SSH
Removals:
git remote rm <remote_name>
- remove remote branch from being trackedgit push -d <remote_name> <branch_name>
- delete remote branch
Removing Files from Git
git rm <file_name>
- remove files from git directory AND working directorygit rm --cached <file_name>
- remove files from git directory ONLYgit rm --cached -r <directory_name>
- remove directory from git directory ONLY
Stashing
git stash show
- show current stashed modificationsgit stash -m "Stash message"
- push current uncommitted changes to the stash loggit stash pop
- pop the most recent set of stashed changes
Command Cookbook
Global Configuration
Create a .gitconfig
file to configure global credentials, settings and aliases across all git repositories:
[user]
name = Luke Miloszewski
email = lukemiloszewski@gmail.com
[github]
user = lukemiloszewski
[init]
defaultBranch = main
[core]
pager = cat
editor = code --wait
[color]
ui = auto
[color "branch"]
upstream = cyan
[log]
abbrevCommit = true
follow = true
decorate = false
[tag]
sort = version:refname
[alias]
aliases = !git config --get-regexp alias | sed -re 's/alias\\.(\\S*)\\s(.*)$/\\1 = \\2/g'
a = add
cm = commit -m
s = status
p = push
pom = push -u origin main
puom = pull origin main
co = checkout
cob = checkout -b
fp = fetch --prune --all
lg = log --graph --date=relative --pretty=format:'%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%an %ad)%Creset'
reword = commit --amend
uncommit = reset --soft HEAD~1
untrack = rm --cache --
Amending the Last Commit
There may be times when you commit changes and realise that you forgot something important that you wanted to include in the snapshot. You can amend the most recent commit to include the changes you made.
git commit -m "Commit message"
git add <filename>
git commit --amend -m "Updated commit message"
- change most recent commit message
Use git commit --amend --no-edit
if you don't need to change the commit message.
Post-Merge Workflow
Once you've closed a pull request and merged a feature branch into the main branch, you can delete that feature branch both locally and remotely (ie: the branch is not needed, you don't need your local machine nor the remote server to keep a reference to it).
On GitHub:
- Close the pull request and merge the feature branch into your main branch
- Delete the feature branch (you should be prompted to do so after closing a PR)
On local machine:
git checkout main
git pull
git fetch -p
git branch -d feature_branch_name
You may receive a warning that prevents you from deleting the local branch if you have changed any commit messages in your PR (ie: if you've squashed any commits). In this case use the -D
flag which will force delete the branch. Just make sure all necessary changes have been pulled in.