Skip to content

Instantly share code, notes, and snippets.

@iknowkungfoo
Last active May 26, 2022 17:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iknowkungfoo/d6567e85ba0361f2838306030b45a961 to your computer and use it in GitHub Desktop.
Save iknowkungfoo/d6567e85ba0361f2838306030b45a961 to your computer and use it in GitHub Desktop.
A collection of common git commands.

Git Quick Start

Configure SSH

Create a new SSH key: ssh-keygen -t rsa

Accept default location, enter a password.

Enter file in which to save the key (/c/Users/user.name/.ssh/id_rsa):
Created directory '/c/Users/user.name/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /c/Users/user.name/.ssh/id_rsa.
Your public key has been saved in /c/Users/user.name/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:<string> <id>
The key's randomart image is:
# ASCII ART

Get the new key: cat ~/.ssh/id_rsa.pub

Copy this whole string and paste into source control SSH key form.

ssh-rsa <longer_string> <id>

Save SSH Key to Mac Keychain

To stop git asking for SSH Key passphrase with every command:

ssh-add -K ~/.ssh/id_rsa

You'll be prompted for the passphrase once, then should not be asked again (persists through restarts).

Load SSH Key with Git Bash for Windows

https://gist.github.com/bsara/5c4d90db3016814a3d2fe38d314f9c23

Configure git

Check current configuration: git config list

Set Global Defaults

git config --global user.email "<email>"
git config --global user.name "<name>"
git config --global init.defaultbranch "main"

Configure Per Folder Defaults

This will override global config values for all repos in the subfolder. Settings in a specific repo will override these settings.

/Code
/Code/foo
/Code/foo/repo1
/Code/bar
/Code/bar/repo1

Create a config file for all repos in a subfolder.

~/Code/foo/.gitconfig_include

Include the folder specific config file in ~/.gitconfig.

[includeIf "gitdir:~/Code/foo/"]
  path = ~/Code/foo/.gitconfig_include

Configure VS Code as Editor

This will open VSCode as the editor for diff, merge and other commands. The editor will remain open until the message has been saved and closed.

https://code.visualstudio.com/docs/editor/versioncontrol#_vs-code-as-git-editor

Add code to PATH.

Make sure you can run code --help from the command line and you get help.

  • if you do not see help, please follow these steps:
    • macOS: Select Shell Command: Install 'Code' command in path from the Command Palette.
    • Windows: Make sure you selected Add to PATH during the installation.
    • Linux: Make sure you installed Code via our new .deb or .rpm packages.

From the command line, run

git config --global core.editor "code --wait"

Now you can run git config --global -e and use VS Code as editor for configuring Git.

Configure Beyond Compare

If you have installed Beyond Compare, configure it for git.

Launch Beyond Compare, go to the Beyond Compare menu and run Install Command Line Tools.

In the CLI, configure as the diff and merge tools.

git config --global diff.tool bc
git config --global merge.tool bc
git config --global mergetool.bc.trustExitCode true

# Diff
git difftool file.ext

#Merge 
git mergetool file.ext

Branches

List Branches

Local only: git branch

Local and Remote: git branch -a

Remote only: git branch -r

Rename a Branch

You can only rename a local branch.

git branch -m <branch>

git branch -m <oldname> <newname>

To "rename" a remote branch, you must delete the remote branch and then push the renamed local branch.

Delete a Branch

From local: git branch -D <branch_name>

From remote: git push origin --delete <branch_name>

Prune dead branches: git remote prune origin

Track a Remote Branch

Tracking allows your local copy to know about the status of the remote copy. For example, if somoene else updates a remote branch you created, git status will reflect that changes need to be pulled.

When pushing a branch to remote for the first time, make sure to add tracking.

git push -u origin feature/branch-name

When you check out a remote branch or forgot to add tracking after the initial push.

git branch --set-upstream-to=origin/<remote> <local>

In the case that you have made changes to your lcoal branch that are radically out of sync w/ remote, you can remove tracking.

git branch --unset-upstream

This could happen when you do a rebase. Even if you delete the remote branch and push your local as a new remote, it will show out of sync until you unset and then again set tracking.

Tags

Rename a Tag

Rename a tag from old to new source:

git tag new old
# Delete the old tag
git tag -d old
# Remove the old tag from the remote repo.
git push origin :refs/tags/old
# Push only the new tag.
git push origin refs/tags/new

Have the team remove the old tag locally:

git pull --prune --tags

Delete / Prune Tags

Delete a local tag:

git tag -d <tag_name>

Delete a remote tag. This syntax avoids name clashes between branches and tags.

git push origin :refs/tags/<tag_name>

When a tag has been deleted from <renote> (e.g. origin), you need to remove them from local as well.

git fetch --prune <remote> +refs/tags/*:refs/tags/*

List Tags with Annotations

This will list up to 99 lines from the annotation/commit message. source

git tag -n99

Move a Tag

In the cast that you need to move a tag (re-tag) to a newer commit on a branch.

git tag -a -f <tag> <new_commit>
# Update the remove reference to the tag.
git push origin --tags -f

Remotes

List Remotes

Aliases Only: git remote

Alias w/ URLs: git remote -v

Managing Remotes

Add remote: git remote add <alias> <url>

Remove remote: git remote remove <alias>

Inspect: git remote show <alias>

Rename: git remote rename <current_alias> <new_alias>

Change remote URL: git remote set-url origin git://<new_url>

Ping Remote: git ls-remote

Working with Stashes

Use this to save work in progress code before switching to another branch. These are saved in .git/refs/stash.

Save WIP code: git stash

Restore most recent WIP code (deletes stash): git stash pop

Restore most recent WIP code (keeps stash): git stash apply

List all stashed code: git stash list

This retuns a list that looks like

stash@{0}: WIP on feature/1234
stash@{1}: WIP on feature/3456
stash@{2}: WIP on feature/5678

Restore a specific stash: git stash apply stash@{1}

Reference a specific stash by adding stash@{x} to the end of most stash commands.

Show list of files in more recent stash: git stash show

Show content of most recent stash: git stash show -p

Show content of a specific stash: git stash show -p stash@{1}

Create new branch from most recent stash: git stash branch <name>

Delete the most recent stash: : git stash drop

Delete all stashes: git stash clear

Working with Commits

See all commits for a single file.

git log --follow <path/to/file>

Diff a file against repo

git diff <commit-hash>:./ -- <path>

Examples:

git diff origin/master:./ -- README.md
git diff HEAD^:./ -- README.md
git diff stash@{0}:./ -- README.md
git diff 1A2B3C4D:./ -- README.md

List of changed files (branch, tag or commit hash). <B> can even be a remote branch.

# File name only
git diff <A> <B> --stat
# Full path
git diff <A> <B> --name-only
# Change status and full path
git diff <A> <B> --name-status
# +/- line count and full path
git diff <A> <B> --numstat

Show all changes in the CLI (verbose).

git diff <A> <B>

Compare changes to a single file.

git diff <A> <B> -- <path/to/file>

Compare changes to a single file in an external diff viewer (e.g. Beyond Compare Mac)

git difftool <A> <B> -- <path/to/file>

Copy a specific change from another branch:

git show <commit_id>:<path/to/file> > <path/to/file>

Checkout a file at a specific commit (source):

Assume commit SHA is a1b234.

git checkout a1b234 -- file1/to/restore file2/to/restore

To revert to the commit before, append -1 (or any count).

git checkout a1b234-1 -- file1/to/restore file2/to/restore

Change a Commit Message

If your commit has not been pushed and you need to update the message, you can change it easily.

git commit --amend

Reverting a Commit

That Never Happened

https://www.git-tower.com/learn/git/faq/undo-last-commit/

Reset will rewind your current HEAD branch to the specified revision. In our example above, we'd like to return to the one before the current revision - effectively making our last commit undone.

Note the --soft flag: this makes sure that the changes in undone revisions are preserved. After running the command, you'll find the changes as uncommitted local modifications in your working copy.

git reset --soft HEAD~1

If you don't want to keep these changes, simply use the --hard flag. Be sure to only do this when you're sure you don't need these changes anymore.

git reset --hard HEAD~1

Revert via New Commit

https://www.atlassian.com/git/tutorials/undoing-changes/git-revert

This will create a new commit that reverts the changes from the original commit.

  • Pull the latest changes to your branch (e.g. develop)
  • Use git log to find the commit hash of the commit to revert.
  • Create a new branch to manage the reversion: git checkout -b revert/ticket
  • Revert the commit: git revert -m 1 <commitHash>
  • Check the diffs against the source branch.
    • git diff develop --name-only to get the list of changed files.
    • Use git diff or git difftool to check the individual files against the original change request.
  • Merge the reversion branch (revert/ticket) back to the source branch (develop).

Rebase

https://jeffkreeftmeijer.com/git-rebase/

Update your feature branch with changes from its source branch, then reapply your changes.

$ git rebase develop
First, rewinding head to replay your work on top of it...
Fast-forwarded feature/1234 to develop.

Squash multiple commits into one.

This will roll multiple commits into a single one which makes for an easier and cleaner merge to another branch.

https://www.youtube.com/watch?v=2E23I9PzplM

Hint HEAD is the most recent commit. HEAD~1 is also the most recent commit.

Rebase back N commits

git rebase -i HEAD~N

Mark the most recent as “pick” or “reword”, the others as “fixup” or “squash”.

Reverting a Bad Merge

Source In the case you've merged code and need to unmerge that colleciton of changes.

git checkout <branch>
git pull
git log

Copy the commit hash (<commit-hash>) related to the bad merge. This should be the most recent commit.

git revert -m 1 <commit-hash>

You'll be prompted to edit a commit message that outlines what files will be affected. Save and close this message, then push the changes to origin.

git push

Deleting a Folder

Remove an entire folder and contents. Source

git rm -r one-of-the-directories
git commit . -m "Remove duplicated directory"
git push origin <your-git-branch> (typically 'master', but not always)

Removing Content from a Repository

StackOverflow

To stop tracking a file you need to remove it from the index. This can be achieved with this command.

git rm --cached <file>

If you want to remove a whole folder, you need to remove all files in it recursively.

git rm -r --cached <folder>

The removal of the file from the head revision will happen on the next commit.

WARNING: While this will not remove the physical file from your local, it will remove the files from other developers machines on next git pull.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment