✨ Unix Shell (Cheat Sheet)

This is a cheat sheet for Unix shell commands (mostly notes-to-self). They are incomplete by default.

NOTE This repo currently contains git commands as well, which I’ll remove at some point.

Unix commands

Zsh shell (configuration)

See code ~/.zshrc

Source: dev.to > Customizing my Zsh Prompt

I borrowed a few commands from 0nn0/terminal-mac-cheatsheet/README.markdown

List and kill processes

From wikipedia :

top (table of processes) is a task manager or system monitor program, found in many Unix-like operating systems, that displays information about CPU and memory utilization.

$ top

Find the PID (process identification number) you want to kill and use kill-9 <PID>.

For example::

kill -9 27201

Source: setapp.com

Create directory: mkdir

# Example:
mkdir a_test_folder
# Example anywhere:
# Example within folder:
cd [folder]

Full path to working directory: pwd

# Example:
pwd .

Short listing: ls

# Example:
ls .

Home directory: ~

# Example:
cd ~

Previous directory: -

# Example:
cd -

Current folder: .

# Example:
ls .

Parent directory: ..

# Example:
ls ..

Move up 2 levels

cd ../../

Create new file: touch

# Example:
touch an_algorithm.py

Remove file: rm

rm an_algorithm.py

Rename folder: mv

mv old_name new_name

Only if new_name is not already a folder.

Move folder: mv

mv old_location new_location
# mv home/user/desktop/folderA home/user/documents/github/folderX

Only if new_location is already a folder.

Delete a directory and its contents

rm -r [dir]

Show head of a file:

head [file].[extension]


Here are a few resources and useful cheat sheets I found to learn Git:

Semantic commit messages

Source: Github gist by joshbuchea

Format: <type>(<scope>): <subject> (<scope> is optional)


feat: add hat wobble
^--^  ^------------^
|     |
|     +-> Summary in present tense.
+-------> Type: chore, docs, feat, fix, refactor, style, or test.

More Examples:

  • feat: (new feature for the user, not a new feature for build script)
  • fix: (bug fix for the user, not a fix to a build script)
  • docs: (changes to the documentation)
  • style: (formatting, missing semi colons, etc; no production code change)
  • refactor: (refactoring production code, eg. renaming a variable)
  • test: (adding missing tests, refactoring tests; no production code change)
  • chore: (updating grunt tasks etc; no production code change)


Create new file

This command creates a file in the directory you are in.

touch test.py

If you want to create and edit a new file or simple edit an existing file in the terminal, you can use vim:

vim test.py

This opens vim where you can edit the file), press i to enter the edit mode, type code, press esc to enter command mode, type : x to save and exit the file.

Create directory

mkdir [dir]

Easiest solution is find your folder path by right-clicking folder > press alt > //Copy “file.md” as pathname// Type cd, paste pathname and press enter

Clone git repository

git clone url

This creates a folder with the repo, so no need to mkdir beforehand.

Pull updates from remote repo

git pull

Check status of staged changes etc

git status

Stage changes

git add [file-name.file-extension]
git add [folder]
git add -A

(to add all changes to files).

It’s useful to know that Git works with the content of files and not files themselves. So when we //add// changes to a file we deleted, we are not //adding// the file to the repo but //adding// the changes to the file (i.e. deletions) to Git.

Commit changes

git commit -m "[commit message]"

If you staged a change where the file was removed the resulting message after committing will look something like this:

1 file changed, 28 deletions(-)
delete mode 100644 <FILENAME>.<EXTENSION>

Push local branch to origin

Don’t push your work until you’re happy with it One of the cardinal rules of Git is that, since so much work is local within your clone, you have a great deal of freedom to rewrite your history locally. However, once you push your work, it is a different story entirely, and you should consider pushed work as final unless you have good reason to change it. In short, you should avoid pushing your work until you’re happy with it and ready to share it with the rest of the world.

Source: git-scm.com

git push -u origin main
git push -u origin my-branch-name

The syntax is:

git push <remote> <branch>

where remote is origin by default and you current branch is used. If your current branch is main, the command

git push

will supply the two default parameters—effectively running

git push origin main

Source: How to push a local Git branch to Origin

Because my repositories are hosted on GitHub, the terminal will ask for your login credentials to push the changes:

Username for 'https://github.com': <USERNAME>
Password for 'https://<USERNAME>@github.com': <personal_access_token>

Once entered, you can see the changes being pushed to the repo.

About personal access tokens:

In Dec 2020, GitHub announced their intent to require the use of token-based authentication (for example, a personal access, OAuth, or GitHub App installation token) for all authenticated Git operations. Beginning August 13, 2021, we will no longer accept account passwords when authenticating Git operations on GitHub.com.

In short, that means you cannot use your account password to authenticate yourself when pushing changes to GitHub from the command line. Instead you will have to use a personal access token that you can generate in Settings > Developer settings > Personal access tokens

Source: Creating a personal access token

I like to check the git status (git status) again to see what changes are left if I haven’t committed all changes.

Rename repo

Source: Renaming a repository

Go into ‘settings’ on GitHub and change the name there manually.

In addition to redirecting web traffic, all git clone, git fetch, or git push operations targeting the previous location will continue to function as if made on the new location.

However, to reduce confusion, we strongly recommend updating any existing local clones to point to the new repository URL. You can do this by using git remote on the command line:

git remote set-url origin new_url

Staging parts of a file

Source: Stack Overflow

git add -p <filename>
# or
git add --patch  <filename>

Git will break down your file into what it thinks are sensible “hunks” (portions of the file). It will then prompt you with this question:

Stage this hunk [y,n,q,a,d,/,j,J,g,s,e,?]?

Here is a description of each option:

  • y stage this hunk for the next commit
  • n do not stage this hunk for the next commit
  • q quit; do not stage this hunk or any of the remaining hunks
  • a stage this hunk and all later hunks in the file
  • d do not stage this hunk or any of the later hunks in the file
  • g select a hunk to go to
  • / search for a hunk matching the given regex
  • j leave this hunk undecided, see next undecided hunk
  • J leave this hunk undecided, see next hunk
  • k leave this hunk undecided, see previous undecided hunk
  • K leave this hunk undecided, see previous hunk
  • s split the current hunk into smaller hunks
  • e manually edit the current hunk. You can then edit the hunk manually by replacing +/- by #
  • ? print hunk help

If the file is not in the repository yet, you can first do git add -N <filename>. Afterwards you can go on with git add -p <filename>.

Afterwards, you can use:

  • git diff --staged to check that you staged the correct changes
  • git reset -p to unstage mistakenly added hunks
  • git commit -v to view your commit while you edit the commit message.

List local branches

git branch

List remote branches

git branch -r

List all local and remote branches

git branch -a

Source: Git Branches: List, Create, Switch to, Merge, Push, & Delete

Create a new branch

git checkout -b my-branch-name

which is short for

git branch my-branch-name
git checkout my-branch-name

Switch to a branch in your local repo

git checkout my-branch-name


git checkout main

Switch to a branch that came from a remote repo

To get a list of all branches from the remote, run this command:

git pull

Run this command to switch to the branch:

git checkout --track origin/my-branch-name

Source: Git Branches: List, Create, Switch to, Merge, Push, & Delete

Delete local branch

git checkout main
git branch --delete branch_name

You can’t delete the branch you’re currently on. First, switch to another branch and then delete

Source: How To Delete a Local and Remote Git Branch

Delete remote branch

git push origin --delete branch_name

In Git, local and remote branches are separate objects. Deleting a local branch doesn’t remove the remote branch.

To delete a remote branch, use the git push command with the -d (--delete) option:

Source: How To Delete a Local and Remote Git Branch

Rename branches (’’master’’ to’’ main)

Rename master branch to newname (in this case ‘main’)

git branch -m master main

Push newname branch to origin and track origin/newname instead of origin/master

git push -u origin main

Change “Default branch” in Settings / Branches in Github

Settings > Branches > click Switch sign > select new default. Double check it worked on the code page under branches (should show default main).

Delete origin/master

git push origin :master

Source: The easy way to rename “master” to “main” in git and GitHub and GitHub Gist by Comevius

Reset local branch to specific commit (e.g. HEAD)

Replacing all branch history/contents (undo commit):

git reset --hard HEAD^

Source: Seth Robertson

Reset remote (origin) to a specific commit


  • go onto main branch
  • reset that branch to a commit locally
  • force push that commit to remote (origin)
git checkout master
git reset --hard e3f1e37
git push --force origin master

Source: Stack Overflow

Move commit from main branch to topic branch

git branch topic/wip          (1)
git reset --hard HEAD~3       (2)
git switch topic/wip          (3)
  1. You have made some commits, but realize they were premature to be in the master branch. You want to continue polishing them in a > topic branch, so create topic/wip branch off of the current HEAD.

  2. Rewind the master branch to get rid of those three commits.

  3. Switch to topic/wip branch and keep working.

Source: git-scm.com

Merge changes from origin/main into a branch

git checkout <your-branch>      # gets you on your branch
git fetch origin        # gets you up to date with origin
git merge origin/main  # merges changes from main with <your-branch>

Source: Stack Overflow

Add additional commit to existing PR

For example, after feedback or PR Review:

git commit -m "These changes are in response to PR comments"
git push -f origin HEAD

Source: Stack Overflow

Listing Your Tags

$ git tag

Source: Git documentation

Creating “lightweight” tags

[A lightweight tag] is basically the commit checksum stored in a file — no other information is kept. To create a lightweight tag, don’t supply any of the -a, -s, or -m options, just provide a tag name:

git tag <tagname>

This time, if you run git show on the tag, you don’t see the extra tag information. The command just shows the commit:

$ git show v1.4-lw
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <[email protected]>
Date:   Mon Mar 17 21:52:11 2008 -0700

    Change version number

Source: Git documentation

Tagging Later

You can also tag commits after you’ve moved past them. Suppose your commit history looks like this:

$ git log --pretty=oneline
15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment'
a6b4c97498bd301d84096da251c98a07c7723e65 Create write support
0d52aaab4479697da7686c15f77a3d64d9165190 One more thing
6d52a271eda8725415634dd79daabbc4d9b6008e Merge branch 'experiment'
0b7434d86859cc7b8c3d5e1dddfed66ff742fcbc Add commit function
4682c3261057305bdd616e23b64b0857d832627b Add todo file
166ae0c4d3f420721acbb115cc33848dfcc2121a Create write support
9fceb02d0ae598e95dc970b74767f19372d61af8 Update rakefile
964f16d36dfccde844893cac5b347e7b3d44abbc Commit the todo
8a5cbc430f1a9c3d00faaeffd07798508422908a Update readme

Now, suppose you forgot to tag the project at v1.2, which was at the “Update rakefile” commit. You can add it after the fact. To tag that commit, you specify the commit checksum (or part of it) at the end of the command:

git tag -a v1.2 9fceb02

You can see that you’ve tagged the commit:

$ git tag

$ git show v1.2
tag v1.2
Tagger: Scott Chacon <[email protected]>
Date:   Mon Feb 9 15:32:16 2009 -0800

version 1.2
commit 9fceb02d0ae598e95dc970b74767f19372d61af8
Author: Magnus Chacon <[email protected]>
Date:   Sun Apr 27 20:43:35 2008 -0700

    Update rakefile

Source: Git documentation

Sharing Tags

By default, the git push command doesn’t transfer tags to remote servers.

You will have to explicitly push tags to a shared server after you have created them. This process is just like sharing remote branches — you can run git push origin <tagname>.

$ git push origin v1.5
Counting objects: 14, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (12/12), done.
Writing objects: 100% (14/14), 2.05 KiB | 0 bytes/s, done.
Total 14 (delta 3), reused 0 (delta 0)
To [email protected]:schacon/simplegit.git
 * [new tag]         v1.5 -> v1.5

Source: Git documentation

Deleting Tags

To delete a tag on your local repository, you can use git tag -d <tagname>. For example, we could remove our lightweight tag above as follows:

$ git tag -d v1.4-lw
Deleted tag 'v1.4-lw' (was e7d5add)

Note that this does not remove the tag from any remote servers. There are two common variations for deleting a tag from a remote server.

The second (and more intuitive) way to delete a remote tag is with:

git push origin --delete <tagname>

Source: Git documentation

Checking out Tags

If you want to view the versions of files a tag is pointing to, you can do a git checkout of that tag, although this puts your repository in “detached HEAD” state, which has some ill side effects:

$ git checkout v2.0.0
Note: switching to 'v2.0.0'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at 99ada87... Merge pull request #89 from schacon/appendix-final

$ git checkout v2.0-beta-0.1
Previous HEAD position was 99ada87... Merge pull request #89 from schacon/appendix-final
HEAD is now at df3f601... Add atlas.json and cover image

In “detached HEAD” state, if you make changes and then create a commit, the tag will stay the same, but your new commit won’t belong to any branch and will be unreachable, except by the exact commit hash. Thus, if you need to make changes — say you’re fixing a bug on an older version, for instance — you will generally want to create a branch:

$ git checkout -b version2 v2.0.0
Switched to a new branch 'version2'

If you do this and make a commit, your version2 branch will be slightly different than your v2.0.0 tag since it will move forward with your new changes, so do be careful.

Source: Git documentation

Updating existing tags

git tag <tag_name_to_update> <hash_code_new_commit>
git push --force origin <tag_name_to_update>

--force because the commit already exists at remote. You can also delete the tag and recreate it to avoid --force.

Source: ToolsQA

Add submodule to repo

git submodule add <URL>

Add submodule to repo in certain location

git submodule add <git@github ...> <folder-structure>/<directory-name>/

Source: Stackoverflow

Remove submodule from repo

  • Run git rm <path-to-submodule>, and commit.

This removes the filetree at <path-to-submodule>, and the submodule’s entry in the .gitmodules  file. I.e. all traces of the submodule in your repository proper are removed.

As  the docs note  however, the .git dir of the submodule is kept around (in the modules/ directory of the main project’s .git dir), “to make it possible to checkout past commits without requiring fetching from another repository”. If you nonetheless want to remove this info, manually delete the submodule’s directory in .git/modules/, and remove the submodule’s entry in the file .git/config.

These steps can be automated using the commands

  • rm -rf .git/modules/<path-to-submodule>, and
  • git config --remove-section submodule.<path-to-submodule>.

Source: Stack Overflow (linked from Atlassian )

Signing commits (Github verified)

To configure your Git client to sign commits by default for a local repository, in Git versions 2.0.0 and above, run git config commit.gpgsign true. To sign all commits by default in any local repository on your computer, run git config --global commit.gpgsign true.

To store your GPG key passphrase so you don’t have to enter it every time you sign a commit, we recommend using the following tools:

  • For Mac users, the GPG Suite allows you to store your GPG key passphrase in the Mac OS Keychain.
  • For Windows users, the Gpg4win integrates with other Windows tools.

Source: Github docs

Further instructions:

List files tracked by git

git ls-tree --full-tree --name-only -r HEAD
  • --full-tree makes the command run as if you were in the repo’s root directory.
  • -r recurses into subdirectories. Combined with --full-tree this gives you all committed, tracked files.
  • --name-only removes SHA / permission info for when you just want the file paths.
  • HEAD specifies which branch you want the list of tracked, committed files for. HEAD is the pointer for the commit you have checked out currently.

Source: dev.to



  • Add tl;dr from cloud computing class with Stelios
  • Add VS Code command code
  • Add GitHub Desktop commands gh
  • Adds curl notes


Source: ChatGPT

The line #!/bin/bash at the beginning of a unix shell script is known as a shebang (or hashbang, pound-bang, or sharp-bang). In Unix-like operating systems, the shebang specifies which interpreter should be used to execute the script. This ensures consistent behavior regardless of the user’s default shell (e.g. zsh, bash, …).

  1. #: In many scripting languages, the hash symbol is used to start a comment. However, when combined with ! as the first two characters of a script file, it gains a special meaning.

  2. !: When the exclamation mark is combined with the hash symbol as #!, it tells the operating system that the file is a script and should be interpreted.

  3. /bin/bash: This specifies the interpreter’s path that should be used to execute the script. In this case, it’s the Bash shell located at /bin/bash. This path can vary depending on the system and the script interpreter. For example, Python scripts often start with #!/usr/bin/env python.

When you execute a script from the command line in a Unix-like system, the system checks the first line of the script. If it starts with #!, it uses the specified interpreter to run the script. If this line is not included, the system will use the current shell to execute the script, which might not be the intended interpreter and can lead to errors or unexpected behavior.

For example, consider the following script:

echo "Hello, world!"

When you make this script executable and run it, the system reads the first line, sees #!/bin/bash, and invokes /bin/bash to run the script. This ensures that the script is executed in the Bash shell, even if the user is currently using a different shell like zsh or ksh.