🔗 Workflow

Github

Tutorial

🔗 Undo commit

See this

Undo the commit, leaving files intact and staged

git reset --soft HEAD^

Undo the commit and un-stage, leaving files intact

git reset HEAD^

Reset to previous commit, throwing away changed made in between

git reset --hard HEAD^

🔗 Remote URL

List existing remotes

git remote -v

Change remote

git remote set-url origin https://change.url.for.origin.to.this

Or if no exiting remotes

git remote add origin https://github.com/user/repo.git

git push --set-upstream origin main

🔗 Syncing

Syncing a github fork

Assuming the fork has already been cloned.

git clone https://github.com/FORK_OWNER/FORK_REPOSITORY.git

The github docs suggests adding an upstream remote.

See configuring a remote for a fork

git remote add upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git

🔗 Info about branches

git remote -v

git remote show upstream

git ls-remote --heads upstream

git branch -a

git branch -r

🔗 Syncing upstream and origin

git checkout main

git pull upstream main

git push origin main

🔗 List logs for path

git log -- path/to/list

git log --oneline -- path/to/list

🔗 Roll back to a commit

See this

git branch temp

git reset --hard 41508773bb0f816a9fbb4c6f60aa4d784b25fc0e

git branch -D temp

🔗 Ignoring files

See this

🔗 Global .gitignore

git config --global core.excludesfile ~/.gitignore_global

🔗 Stashing

See this

Stash changes

git stash

Working directory should be clean

git status

There can be multiple stashes

git stash list

Apply the most recent stash

git stash apply

Apply a specific stash

git stash apply stash@{2}

Apply stash and re-stage files

git stash apply --index

Remove a stash

git stash drop stash@{0}

Un-apply a stash

git stash show -p stash@{0} | git apply -R

🔗 Cleanup project dir

Remove unused files from .git

If you added the files and then removed them

git fsck

git prune

🔗 PR from fork

Creating a pull request from a fork

  • Click “New pull request” in the original repos
  • Use base branch drop-down menu to select the branch of the upstream repository
  • Use the head fork drop-down menu to select your fork
  • Use the compare branch drop-down menu to select the branch with changes

🔗 Fetch branch from upstream

…that does not exist in origin

The git pull command does a fetch and merge, it changes the working copy.

To update the remote-tracking branches without changing the working copy, use the git fetch command

git fetch upstream/BRANCH

Track the remote branch

git checkout -b BRANCH upstream/BRANCH

Make some changes and push to origin

git commit -a -m "Changes to branch..."

git push origin BRANCH

Now use github to compare with upstream

🔗 Show tracking

Show which branches are tracking what

git branch -vv

🔗 Change tracking

Change the remote a git branch is tracking

git branch BRANCH -u upstream/BRANCH

🔗 Restoring deleted files

Find and restore a deleted file

Find the commit where the file was deleted

git log --diff-filter=D --summary | grep -C 10 FILE_NAME

Restore the deleted file, use tilde to refer to the nth grandchild of the commit.

git checkout COMMIT_HASH~1 filename

🔗 List files in commit

List all the files in a commit

🔗 User facing (porcelain) command

git show --pretty="" --name-only 5e7b36e

🔗 List changes in branch

See all changed files on a branch

With branch checked out

git diff --name-only main...

If not on branch

git diff --name-only main...BRANCH_NAME

List changes per commit

git whatchanged --name-only

Compare changes for folder (directory) at path, see this post

git diff main..yourbranch path/to/folder

🔗 Plumbing command for use in scripts

List all files in the commit

git ls-tree --name-only -r 5e7b36e

List changed files only

git diff-tree --no-commit-id --name-only -r 5e7b36e

🔗 Remove commits from remote

Remove commits from a remote branch

Use git reset to remove the commit

Push revised local branch to the remote

git push origin --force

🔗 Protect a branch

Protected branches and required status checks

“…gives repository administrators the ability to disable force pushes to specific branches.”

🔗 Pull with rebase

Pull with rebase

Use this to git pull and re-formulate “local changes to be relative to the newer version”. Useful when working on the same branch as someone else. No need to merge and clutter the history.

Behaves similar to svn update.

🔗 Work on a branch

Create a new branch of development at the current commit (HEAD)

git checkout -b BRANCH_NAME

Reapply branch commits on top of main

# Only do this if branch is not pushed yet
git fetch
git rebase origin/main

Push branch and add upstream tracking. Upstream tracking is useful for displaying server changes with git status. Many commands will apply to the upstream tracking branch by default

git push -u origin BRANCH_NAME

After push don’t rebase rather merge main

git merge main

Merge branch

git checkout main

git merge BRANCH_NAME

Merge branch as one commit

git merge --squash BRANCH_NAME

git commit -m "Merged BRANCH_NAME"

Delete local branch

# Use --force or -D to to delete irrespective of its merged status
git branch -d BRANCH_NAME

Delete remote branch

# Make sure the remote branch is not deleted already
git fetch --prune

git push origin --delete BRANCH_NAME

🔗 Merge commits

How to avoid merge commits from git pull

This is useful when working on the main branch locally

Commit local changes

Pull and re-write history to apply local commits after remote commits

git pull --rebase

Push as usual

🔗 Removing history

Remove sensitive data from history

export SENSITIVE_DATA="path/to/config.js"

git filter-branch --force --index-filter \
'git rm -r --cached --ignore-unmatch ${SENSITIVE_DATA}' \
--prune-empty --tag-name-filter cat -- --all

echo "${SENSITIVE_DATA}" >> .gitignore

Search for file in history

git log --all --full-history -- ${SENSITIVE_DATA}

export SENSITIVE_SHA="123ABC"
git show ${SENSITIVE_SHA} -- ${SENSITIVE_DATA}

Push to remote

git push origin --force --all

git push origin --force --tags

Force all objects in your local repository to be de-referenced and garbage collected

git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin

git reflog expire --expire=now --all

git gc --prune=now

🔗 List all remote branches

Git not listing all remote branches

Remove and add remote, then fetch all

git remote remove origin
git remote add origin https://github.com/path/to/repos.git

🔗 Split dir to new repo

Splitting a subfolder out into a new repository

Filter sub folder from the rest of the files

git clone https://github.com/USERNAME/REPOSITORY-NAME

cd REPOSITORY-NAME

git filter-branch --prune-empty --subdirectory-filter FOLDER-NAME  BRANCH-NAME

Create a new git repos and setup remote url

git remote -v

git remote set-url origin https://github.com/USERNAME/NEW-REPOSITORY-NAME.git

git push -u origin BRANCH-NAME

🔗 Terminal prompts

go get results in ’terminal prompts disabled’

env GIT_TERMINAL_PROMPT=1 go get xxxx

🔗 Reset origin

Git reset origin to specific commit

WARNING This will remove all commits that came after SHA

git reset --hard SHA
    
git push --force origin main

🔗 Signing commits and tags

Github marks commits and tags as “Verified” if they are signed

Configure your account with your SSH public key, e.g. ~/.ssh/id_rsa.pub

Then configure your Git client to sign all commits by default

As per this post: “Git version 2.34 and later supports signing commits and tags with SSH keys — no GPG key needed”

Upgrade git if required

brew install git

Set global ~/.gitconfig

git config --global commit.gpgsign true
git config --global gpg.format ssh
git config --global user.signingKey /path/to/your/.ssh/id_rsa.pub

New commits and tags should now display the verified mark

🔗 Dropbox

git-remote-dropbox: "…is a transparent bidirectional bridge between Git and Dropbox. It lets you use a Dropbox folder or a shared folder as a Git remote"

Setup

Remember to set selective sync and the dropbox folder

🔗 Push existing repo to dropbox

git remote -v

git remote add origin "dropbox://nosync/REPOS"

git push --set-upstream origin main

🔗 Clone repo from dropbox

git clone dropbox://nosync/REPOS

git will not automatically checkout a branch, why?

git branch -a