Starting a Project like a Power User
Tags: commandline, git, github, tutorial
Published: 2022-01-26 02:38:49

Have you ever wondered how some power users do everything from the command line? Well, then you have come to the right place. In this guide, I will help you dip your toes in by starting a project and ultimately pushing it to GitHub all from the command line. We will use a bit of the terminal, a bit of the integrated terminal within a text editor, and some of the command line interface tools provided by GitHub. With that said, there are a few prerequisites, if you will, that are helpful to follow along with this guide. Firstly, it is not imperative that you deeply understand each of these tools, but it is certainly beneficial to know of them. We will be using zsh and oh-my-zsh as the terminal shell. A shell is a program that allows you and other programs to interact with your computer’s operating system. Z shell, or zsh for short, is just one of the many shells and command languages. It is fairly common, so you may already have it. If not, I have provided a download link along with all the other tools used in this guide. Oh-my-zsh is a framework for zsh that helps manage plugins and allows for themes, among other things. Like, zsh, it is not required for this guide but for the sake of continuity, I wanted to make you aware of what I use. If you are using another shell (like bash, for instance) you may have a `$` preceding all command line prompts instead of the `→` seen in this guide. The actual commands used in the command line are fairly ubiquitous among most default shells. We will be using VS Code for the text editor. Again, you can use another as long as you figure out how to access its built-in command-line interface. And finally, the version control system we will be using is git with GitHub. These two are essential to the guide as the commands used are specific to them. Below you can find links to acquire all of the tools used.

### Essential:

- [git](https://git-scm.com/downloads)
- [GitHub](https://github.com/)

### Useful but not required:

- [VS Code](https://code.visualstudio.com/)
- [zsh](https://github.com/ohmyzsh/ohmyzsh/wiki/Installing-ZSH)

### Optional:

- [oh-my-zsh](https://ohmyz.sh/)


## The Guide


### Navigation

We will start by opening up the terminal. Once open we will be met with a screen that looks something like this:

```
-> ~ 
```

If you have leftover entries from a previous session or your terminal window seems busy, you can type the command `clear` at any time to clear the window. This command does not delete anything or take any meaningful action. It just cleans up your workspace so you can start with a clean slate (as seen in the pictures below). You can always scroll up to see previously cleared information. (Note: any time you type in a command, you must hit enter to execute it).

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ehkls8j5qv39b154o9nk.png)

```
-> clear
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c99do75ysusnuleiq2p6.png)

Once your terminal is cleared, type in the list command.

```
-> ~ ls
```

This will list out all of the contents of our current directory (directory or folder can be used interchangeably, ‘directory’ is just the more technical term). If you are in your root directory (think of this as the outermost, home folder), your terminal will look something like this:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9loezboskv7fihql78qm.png)

This is essentially showing the same information as if we were to open Finder (macOS) or the start icon (Windows); we are just accessing it in a different way. Finder or the start menu is part of the graphical user interface (GUI), and your terminal grants access to the command-line interface (CLI).

Alright, now let us find where we want our new project to live. You will likely house your documents in your documents folder, so let’s go there. To change folders, we will use the change directory command.

```
-> ~ cd ~/Documents
```

The `cd` portion changes the directory, and the `~/` portion designates to which directory. The tilde `~` means a relative path. Technically, when changing directories, we need to spell out the exact address. We use the tilde to forgo typing the absolute (exact entire address) path. If you ever need the absolute path, type `pwd` (print working directory) to view it. If we do so in the `/Documents` folder, we will get something like this:

```
-> Documents pwd
/Users/myusername/Documents
```

The relative path becomes increasingly useful as we dive deeper into layered directories. Additionally, if you are using zsh, the tab key allows you to autocomplete folder names and the tilde is not required to change folders housed in the current working directory (the folder you are currently in).

Another essential navigation command is the two dots.

```
-> ~ cd ..
```

Typing `cd` followed by a space and two periods will move you out of the current directory back to its parent directory. If we use the directory in the `pwd` example, typing in the `..` command will move us from `/Documents` to `/myusername`.

### Creation & Deletion

Let us say we want to create a project in our `/Documents` folder. Make sure you are there by either confirming with `pwd` or moving there with `cd` (as seen below, your terminal will also often print your current directory following the `→` or `$`). Once there, we want to make a new folder to house all the project files.

```
-> Documents mkdir my_new_project
```

The make directory command `mkdir` creates a new folder named with whatever string we provide after the command. Now a heads up, if you want spaces in the name, you must wrap the name in quotes.

If we happen to misspell the new folder name, there are a few ways to handle it. We can use the `mv` command and move the folder to the same place with a new name.

```
-> Documents mv ~/Documents/my_misspelled_proj ~/Documents/my_correctly_spelled_proj
```

Or we can delete the folder with `rmdir` and create a new one.

```
-> Documents rmdir ~/Documents/my_misspelled_proj
-> Documents mkdir ~/Documents/my_correctly_spelled_proj
```

Tip: if you put files in your directory but still want to delete the folder, including its contents, `rmdir` alone will not work. It only works on empty directories. If the directory has contents and you want to delete the folder AND its contents, you must use one of the following:

```
-> Documents rmdir -r ~/Documents/my_misspelled_proj
```
or

```
-> Documents rm -r ~/Documents/my_misspelled_proj
```

The `-r` stands for recursive and will cause all contained files to be deleted. The `rm` is the standard remove function. This will remove files. A huge heads-up, deleting things from the command line is permanent, and there is no confirmation. You will not receive an ‘are you sure?’ message, and the files/folders will not be in the trash. They are gone. This can be said regarding all actions taken from the command line but proceed with caution. Most small commands (i.e. commands covered in this guide) are of little to no consequence. However, as you become more adept with CLI tools, you will find yourself putting together more complex commands, at which point you will want to be very clear on what that command will accomplish.

Moving on. Once we create the folder we want to house our project files, we will `cd` into the folder and then create said files. Observe:

```
-> Documents cd my_new_project
-> my_new_project touch index.html styles.css script.js
```

The touch command creates files with the names we provide. At this stage, we must designate the file types. As seen above, we have created an HTML file, a CSS file, and a JavaScript file. You can make as few or as many files following the touch command. Once entered, use `ls` to verify their creation.

```
-> my_new_project ls
index.html styles.css script.js
```

We will get something like the above. Once verified, we can open these files directly in our default editor by typing `code .`.

```
-> my_new_project code .
```

The dot or period tells the computer that we want the preceding command to apply to all the files in the current directory. You can alternatively type the files’ names directly, and this is obviously useful if you want to open only one or some of the files in the folder.

Once the `code` command is entered, VS Code will automatically open in a new workspace with the selected files. From here, we can start building away.

### Version Control & Pushing to GitHub

Let us fast forward a bit and say we have completed the first version of our app/site. We still have all of our files open in VS Code, and we have saved our progress locally to our machine. From here, we need to make sure we can control its version and push our progress to a remote repository. Open the integrated terminal from the terminal menu within VS Code. By default, you should be in your project’s directory. If you are unsure or need to do some navigation, use the commands laid out previously.

At this point, you will want to ensure that your GitHub CLI is set up properly. If you already have a GitHub account, it is likely just a matter of running `brew install gh` (macOS) or viewing the [CLI README.md](https://github.com/cli/cli#installation) to install it, and then run `gh auth login` to ensure your account is connected. Visit [GitHub’s CLI docs](https://cli.github.com/manual/) for further instruction/clarification.

If you think you have already run these steps or want to confirm you have done them correctly, running `gh auth login` can verify your status. If done correctly, you will get this message

```
➜  my_new_project gh auth login

? What account do you want to log into? GitHub.com
? You're already logged into github.com. Do you want to re-authenticate? No
```

Enter no when prompted. Now let us initiate our git repository.

```
➜  my_new_project git init
```

```
➜  my_new_project git init
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint: 
hint:   git config --global init.defaultBranch <name>
hint: 
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint: 
hint:   git branch -m <name>
Initialized empty Git repository in /Users/myusername/Documents/my_new_project/.git/
➜  my_new_project git:(master) ✗ 
```

When done, we will get the above message as confirmation. You will notice via the ‘hint:’ that you can change the name of your initial branch. As you can see, I have never bothered.

Now to add files to staging. To see what files can be staged, use `git status`.

```
➜  my_new_project git:(master) ✗ git status
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        index.html
        script.js
        styles.css

nothing added to commit but untracked files present (use "git add" to track)
➜  my_new_project git:(master) ✗ 
```

You can see that we have three ‘untracked’ files. To add all of them to be committed, we can type `git add .`. As you may remember the `.` allows us to add all the files without having to type each individually. The `.` will not be used in all cases as many projects will contain files we do not want to commit, but in this case, it will work just fine. Once we have run `git add .`, we can recheck the status.

```
➜  my_new_project git:(master) ✗ git add .
➜  my_new_project git:(master) ✗ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   index.html
        new file:   script.js
        new file:   styles.css

➜  my_new_project git:(master) ✗ 
```

You will notice we now have files listed under Changes to be committed. Perfect. We can now commit our changes.

```
➜  my_new_project git:(master) ✗ git commit -m 'first commit'
```

You can commit without a message (`-m` followed by the message contained in quotes) but I highly discourage you from doing so. It is always good to have some indication as to what the commit is doing.

Once we hit enter, we will get more confirmation information. Something like this:

```
➜  my_new_project git:(master) ✗ git commit -m 'my message'
[master (root-commit) 5d104wg] my message
 3 files changed, 22 insertions(+)
 create mode 100644 index.html
 create mode 100644 script.js
 create mode 100644 styles.css
➜  my_new_project git:(master) 
```

And finally, we will want to create our new GitHub repository and push it there.

```
➜  my_new_project git:(master) gh repo create
? Repository name my_new_project
? Repository description a great description
? Visibility Public
? This will add an "origin" git remote to your local repository. Continue? Yes
✓ Created repository josiahwebb/my_new_project on GitHub
✓ Added remote htps://github.com/josiahwebb/my_new_project.git
➜  my_new_project git:(master) 
```

`gh repo create` will create a repository named after the directory that we are in currently. That would be ‘my_new_project’ in this case. We will then answer a series of questions, as seen above. We can rename the repo with the first question, designate its description with the second, and denote its visibility (private/public) with the third. The fourth question essentially asks what we want our remote server to be named. In other words, instead of instructing git to push my commits to a remote server at https://github.com/josiahwebb/my_new_project.git every time, I can say push it to origin (as you will see below). Origin is simply the default name; you can change the name if you wish. After creating the repo, you will now be able to see it on your GitHub profile. The last step is to push our files to the new repo.

```
➜  my_new_project git:(master) git push -u origin master 
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 603 bytes | 603.00 KiB/s, done.
Total 5 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/josiahwebb/my_new_project.git
  [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
➜  my_new_project git:(master) 
```

The initial push will need the entire `git push -u origin master` command. `-u` is not necessary but quite handy. If we include that in our initial push, any subsequent pushes only need `git push` as long those pushes are going to the same branch. The `-u` tag is short for `--set-upstream-to` and, as you might infer, it sets the default branch for future git commands within this project.

And there we have it. We have created a project entirely from the command line. There is obviously a lot more to git, GitHub, and the command line, but I hope this guide at least helps get you started. I know something like this would have been immensely helpful when I first started. Thanks for reading!

gm