Git


Repos

Initialise a git repo

Make a .gitignore file. In terminal:

touch .gitignore
 
echo ".DS_Store" > .gitignore

Make directory into git repo and connect to remote:

git init
git add .
git commit -m "init"
git remote add origin https://github.com/USER/REPO.git

Now you have two options: Push everything to remote repo:

git push -u origin master 
# Or "origin main"
 
# for force push add "--force"

Pull everything from remote repo:

git pull origin master

Pull from another repo

git remote add upstream https://github.com/user/repo.git
 
git pull upstream

Pulling another branch and then merging it

git fetch origin master:master
git merge master

Delete a git repo

  • Option 1: CMD + SHIFT + . to show hidden files
  • Option 2: rm -fr .git in the folder that has the repo

Rename a repo

  1. Go to the remote host (for example, https://github.com/User/project).
  2. Follow the host’s instructions to rename the project (will differ from host to host, but usually Settings is a good starting point).
  3. Go to your local repository directory (i.e., open a command prompt and change to the repository’s directory).
  4. Determine the new URL (for example, [email protected]:User/project-new.git)
  5. Set the new URL using Git:
git remote set-url origin [email protected]:User/project-new.git

Branches

# Create branch
git branch BRANCHNAME
# Create and move
git checkout -b BRANCHNAME
 
# Move Head pointer (what's active)
git checkout BRANCHNAME
 
# Differences between branches
git diff master..BRANCHNAME
 
# Merge into master
git merge BRANCHNAME
 
# See merged
git branch --merged
 
# Delete branches
git branch -d BRANCHNAME
 
# See all branches
git log --all --decorate --oneline --graph
 

Rename branches: How to Rename a Local and Remote Git Branch – A Quick Guide

Manually approve each change in a merge

git merge --no-commit --no-ff merge_branch

Merge and delete a branch

Local

git merge source-branch && git branch -d source-branch

Remote

git push origin --delete branch

Commits

Conventional commits

Using emoji in commits

Source: https://opensource.com/article/19/2/emoji-log-git-commit-messages

  1. Imperative
  • Make your Git commit messages imperative.
  • Write commit message like you’re giving an order.
    • e.g., Use βœ… Add instead of ❌ Added
    • e.g., Use βœ… Create instead of ❌ Creating
  1. Rules
  • A small number of categories are easy to memorize.
  • Nothing more, nothing less
    • e.g. πŸ“¦ NEW, πŸ‘Œ IMPROVE, πŸ› FIX, πŸ“– DOC, πŸš€ RELEASE, and βœ… TEST
  • Actions
  • Make Git commits based on actions you take.
  • Use a good editor like VSCode to commit the right files with commit messages.
  1. ✨ NEW: IMPERATIVE_MESSAGE
  • Use when you add something entirely new.
    • e.g., ✨ NEW: Add Git ignore file 2.πŸ‘Œ IMPROVE: IMPERATIVE_MESSAGE
  • Use when you improve/enhance piece of code like refactoring etc.
    • e.g., πŸ‘Œ IMPROVE: Remote IP API Function
  1. πŸ› FIX: IMPERATIVE_MESSAGE
  • Use when you fix a bug. Need I say more?
    • e.g., πŸ› FIX: Case converter
  1. πŸ“ DOC: IMPERATIVE_MESSAGE
  • Use when you add documentation, like README.md or even inline docs.
    • e.g., πŸ“ DOC: API Interface Tutorial
  1. πŸš€ RELEASE: IMPERATIVE_MESSAGE
  • Use when you release a new version.
    • e.g., πŸš€ RELEASE: Version 2.0.0
  1. βœ… TEST: IMPERATIVE_MESSAGE
  • Use when you release a new version.
    • e.g., βœ… TEST: Mock User Login/Logout

Misc

Remove a file

git rm <file>
git rm -r <folder>
git commit -m "Deleted the file from the git repository"

Clean up loose object error

git gc --aggressive --prune=now

Submodules

git submodule add https://github.com/url-to-submodule
 
# Update submodule:
git submodule update --recursive --remote

Ignore all subdirectories

# In .gitignore:
**/

Generating release notes from git commit messages using basic shell commands (git/grep) | SAP Blogs

git log --pretty="- %s"

Since last release

git log $(git describe --tags --abbrev=0)..HEAD --pretty=format:"%s"

My categories

✨ New

git log $(git describe --tags --abbrev=0)..HEAD --pretty=format:"%s" -i -E --grep="^✨ NEW: "

πŸ‘Œ Improvements

git log $(git describe --tags --abbrev=0)..HEAD --pretty=format:"%s" -i -E --grep="^πŸ‘Œ IMPROVE: "

πŸ› Bugs

git log $(git describe --tags --abbrev=0)..HEAD --pretty=format:"%s" -i -E --grep="^πŸ› FIX: "

πŸ“ Docs

git log $(git describe --tags --abbrev=0)..HEAD --pretty=format:"%s" -i -E --grep="^πŸ“ DOC: "

My aliases

  • release [VERSION NO]: Release a new Obsidian version

Workflow

Inspired by A successful Git branching model Β» nvie.com

Main branches (infinite lifetime)

  • main: code is always production-ready
  • dev: always reflects the latest working changes

dev merges into main when code is stable. Therefore each dev into main merge is a new release by definition

Supporting branches (limited lifetime)

Feature/topic branches

  • may branch off from: dev
  • must merge back into: dev
  • naming convention: iss2 Merge with git merge --no-ff myfeature to not loose history

Release branches

  • may branch off from: dev
  • must merge back into: dev and main
  • naming convention: release-*

Branch of from dev when it is almost ready for another release.

Hotfix branches

  • may branch off from: main
  • must merge back into: dev and main
  • naming convention: hotfix-*

They are like release branches but unplanned.

Resetting local changes

  • git reset --hard HEAD reset back to HEAD of the branch
  • git clean -df Discard any new files or directories