Backing up your work and using version control software

Backing up your work and version control software

Backing up your work

Simply making a backup copy on an external USB drive is better than nothing. But, it is easy to forget to make copies this way. So, it is better to use some kind of cloud storage that automatically saves your work. If you do a search on Google for something like "free cloud storage with sync", you will probably see options like Google Drive, pCloud, MEGA, Dropbox and Microsoft OneDrive. The amount of free storage varies, but these all would provide enough backup for anyone learning the basics of web programming. This site: Zapier - The best cloud storage apps in 2025, you will see a summary of a number of those services. I use Dropbox and pCloud. I think that Dropbox has faster syncing, but I mainly use pCloud because I can use pCloud on any number of computers. Dropbox limits the syncing to a maximum of 3 computers for their free plan. With pCloud, I responded to a special offer to get more storage if I invited someone else to use their services and they joined. So, I managed to get 20 GB of free storage. This is more than what I need, as I don’t store things like audio or video files there.

So, if you can get some free cloud storage and sync it with the folders that you use for your programs, this is a good form of backup. Be careful, as some of those providers only sync one folder. pCloud lets you sync a folder with many subfolders, so that works for me. Another thing to keep in mind, is that if you only use sync files as your backup, changing the files locally will result in them being changed on the cloud. Deleting your local files will also be synced to the cloud. So, you need to be careful about what you sync. I use folders outside of my synced area when I am experimenting and only move files into the synced are when I know that I want to keep them. That way I can do anything I want in the experimental area without accidentally deleting or changing files that I did not intend.

Using version control software

Although having a backup copy is a good thing, for any project that involves a large amount of code, it better to keep different versions of your code. This allows you to go back to a previously working version, in case the code somehow gets messed up. Also, unlike just backing up your work, this prevents you from deleting files that you did not intend to delete.

Version control software also allows you to make branches where you can try out ideas, without breaking the main source code. If the experimental code turns out to be useful, you can merge that with the main branch to bring the main branch up to date.

The version control software I use is Git. This is the most popular version control software at this time, so it is well worth learning.

Using Git

If you are using CodeSandbox, using Git for a sandbox is different from a devbox. For many of the lessons we will be using CodeSandbox sandboxes, not devboxes. This conserves resources, and a full devbox is not needed until you start doing things on the server-side (backend). Once we get to a lesson that utilizes a devbox, you can use Git in the same way that is done for a local Git repository.

Installation of Git

On CodeSandbox, Git is already installed, so you don’t have to do anything to use it.

Git installation on Ubuntu Virtual Machine

If you are using the Ubuntu 24.04 virtual machine as discussed in this guide: Ubuntu 24.04 Virtual Machine, you can run the following commands:

$ sudo apt install git

Git installation on Windows 11

Start by going to the following site: git for windows. Click on the Download button. In your regular account, open up the downloaded .exe file. Click on the defaults for the first few steps. When you reach the Adjusting the name of the initial branch in new repositories step, you can choose the Override option and set main as the default branch name.

You can just click on the defaults for the rest of the steps. Since you installed this in a regular account, it will be installed just for that user. If you had accepted all of the defaults, this would be okay as git will still work the way we need it to.

After installation, go to the Search next to the Start button and type in 'git bash'. The Git Bash app should show up.

git bash windows

If you right-click on the Git Bash app and select Pin to Taskbar, it will now show up in your Taskbar:

git bask taskbar

Git installation on MacOS

The following assumes that you don’t have admin privileges on your Mac computer. The idea is to install Homebrew as a regular user. Then, use Homebrew to install Git. So, open a Terminal and enter the following commands:

% mkdir ~/homebrew
% curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C ~/homebrew

The first command will create a directory called homebrew inside your home directory. The second command will download and extract the homebrew executable into the bin directory inside of your homebrew directory. Since my regular user account’s username is student. This means that the homebrew executable is inside the /Users/student/homebrew/bin directory. So, if you replace 'student' with your username, this will be the full path to that directory.

Now, we need to add that directory to the PATH in your ~/.zshrc file. You can do that with the following command:

% echo 'export PATH="$PATH:~/homebrew/bin"' >> ~/.zshrc

This will append that directory to the end of the $PATH variable. You can now run the ~/.zshrc file with the following command:

% source ~/.zshrc

To test that this has worked, run the following:

% brew -v
Homebrew 4.6.3

You will see the version of Homebrew that has been installed.

Finally, you can install Git.

brew install git

If you type the following command:

% git --version

and you see a version, this has worked. Note that you will get a long warning message when you install Git this way:

Warning: The following directories are not writable by your user:
/usr/local/Cellar
/usr/local/Frameworks
/usr/local/Homebrew
/usr/local/bin
/usr/local/etc
/usr/local/etc/bash_completion.d
/usr/local/include
/usr/local/lib
/usr/local/lib/pkgconfig
/usr/local/opt
/usr/local/sbin
/usr/local/share
/usr/local/share/doc
/usr/local/share/man
/usr/local/share/man/man1
/usr/local/share/man/man3
/usr/local/share/man/man5
/usr/local/share/man/man7
/usr/local/share/man/man8
/usr/local/share/zsh
/usr/local/share/zsh/site-functions
/usr/local/var/homebrew/linked
/usr/local/var/homebrew/locks
/usr/local/var/log

This warning can be safely ignored, as you installed Homebrew in your regular user account.

Using a local Git repository

Here are some links to using Git that you may find useful:

Version control software, of which Git is an example, is software that allows you to keep multiple versions of text files. So, it is very useful for programmers to use for storing their code. Having multiple versions of code allows the programmer to revert back to an earlier working version, in case something they try breaks the code in a way that would be difficult at best to fix. Version control software also allows the creation of branches. A programmer can create a branch from their main code, to try out something experimental. This way, the main code is left untouched until the experimental branch proves to be better. At that point, version control software will allow merging of the experimental branch into the main branch. At that point, the main branch will have been updated to use the new features that were tested in the experimental branch.

If a programmer is working with a group of other programmers, it is common for each programmer to be working in a separate branch of their own. This way, the main code is left intact. That minimizes the chance that code you are working suddenly breaks because of something another person made a change to. A very important concept in making this kind of programming work, is in the usage of regression testing. This means that any updates to code must be run through regression tests that ensure that existing functionality is preserved. So, a programmer works in their own branch of the code. Before that programmer is allowed to merge her/his branch with the main branch, their branch must past not only their own tests for correct functionality, but also the regression tests for the entire project. Failure to adhere to this process, or even worse failing to even have regression tests is courting disaster for that project. So, all programmers that work with other programmers on the same project must develop unit tests for their code, and make sure their branch passes all the unit tests for the whole project. If a programmer does not add their unit tests to the main branch when they merge their branch into the main branch, that programmer has no one else to blame if another programmer’s code breaks their code. The idea behind creating unit tests and regression testing as a whole is beyond what we will cover in the lessons. But, it is something that if you want to work as a programmer, you need to be up to speed on.

It is easier to get started with Git if you are using a local repository at first. If you are using a CodeSandbox sandbox, you cannot use Git locally, so that will be covered after this section. The examples covered here will assume that you have a Documents folder in your home directory and that your username is student. So, substitute your actual username whereever you see student in these examples. So, on an Ubuntu 24.04 virtual machine, the folder that we start with is /home/student/Documents. On Windows 11, the folder would be C:\Users\student\Documents. On MacOS, the folder would be /Users/student/Documents. The following commands should work for any of these cases:

$ cd ~/Documents
  or
> cd ~/Documents
  or
% cd ~/Documents

The '$' symbol just represents the prompt that is commonly used in Linux. For Windows 11, the prompt symbol would '>'. For the MacOS, the prompt symbol would be a '%' symbol. For these lessons, I will usually stick to the $ sign prompt, as I work primarily in Linux. Here is a simple workflow for using Git locally.

  1. Create a directory where you will store your source code.

  2. Initialize that directory using git init

  3. If you are using Git for the first time on that computer, you should configure Git for your email and username.

  4. Place your initial file or files in that directory.

  5. Run git status to see the files that Git wants to start tracking. Here, tracking means keep track of version of that file. You should create a .gitignore file to designate files/directories that should not be tracked. Then, you can run git status again to check that you are tracking only the files you want to track.

  6. Run git commit -m "initial commit". The -m is used to include a message that describes the nature of that commit. In this example here, "initial commit" is often used to signify that this is the first commit to keep track of. The git commit command commits the version of the files currently stored. If you subsequently make some hard to fix mistake in the code, you can revert to one of the earlier versions.

  7. Edit the code. Use git diff <version> to see the differences since the last commit.

  8. Run git commit -m "text explaining change" to commit the changes with a message that describes the change.

That is a very brief overview of a workflow using Git. Let’s go through an example so that you can get a better idea of how the commands mentioned in that workflow and some other important commands are used.

Let’s make a directory called test inside our Documents directory. Within that directory, let’s create the file index.mjs. Let’s create that file, using Visual Studio Code. Before starting up Visual Studio Code, let’s create the directory in the command prompt:

$ mkdir ~/Documents
$ cd ~/Documents
$ mkdir test
$ cd test
$ pwd

On line 1 we make a directory called Documents inside your home directory (~). If that directory already exists, the command will fail, but the command on line 2 will work either way. After line 2, you will be inside the Documents directory of your home folder. Line 3 will make a directory named test inside your Documents folder. On line 4 you change into that test directory. On line 5 the pwd function is called to print working directory. So, on a Linux machine, pwd will print /home/student/Documents/test after running these commands. If you are on Windows, pwd will print C:/Users/student/Documents/test, and on MacOS, pwd will print /Users/student/Documents/test.

After you create that test directory, start up Visual Studio Code. On the left menu, click on Explorer. Then, click on the Open Folder button. Open the folder Documents/test. Then click on New File…​. Enter the name index.mjs and save this file to the test folder you just created.

index.mjs create

Edit index.mjs so that it has the following lines:

index.mjs ver1

Here is the code for index.mjs, in case you want to copy and paste into the editor:

/home/student/Documents/test/index.mjs
if (document.readyState === "loading") {
  document.addEventListener('DOMContentLoaded', init);
} else {
  init();
}

function init() {
  console.log('init called');
}

Let’s create another file, index.html. In VS Code, next to TEST, hover the mouse until you see the symbols with the + sign for adding a new file or a new folder. Click on the button for a new file:

another new file

Type in the name index.html and add the following lines:

index.html ver1

Here is the code in case you want to copy and paste:

/home/student/Documents/test/index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <script type="module" src="./index.mjs"></script>
  </head>
  <body>
    <h1>Hello</h1>
  </body>
</html>

Those files would actually create a simple web page that uses JavaScript. The main thing to understand here, is that we now have some files in our test directory. So, now we will initialize Git for this directory:

$ cd ~/Documents/test
$ git init

If this is the first time you are using Git for this user on this computer, you should do some configuration to set your global email and global username values:

$ git config --global user.email "your_email_username"
$ git config --global user.name "your_name"

By default, git may be using master as the name of the initial branch. We want to change the name to main. So, run the following command to set the branch name:

$ git branch -m main

To check to see that we are on the main branch, use git status

$ git status
On branch main

No commits yet

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

nothing added to commit but untracked files present (use "git add" to track)

You will see something like this. The first thing that is shown is that we are on branch main. No commits have been made and index.html and index.mjs are not being tracked yet. So we need to add those files to be tracked using git add. Here is the command to add all the files in the directory:

$ git add .

The . at the end for current directory means that all the files in the directory will be added.

After running git add ., you can run git status again and you will see that the files are being tracked now.

$ git status
On branch main

No commits yet

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

Now, we can do our first commit.

$ git commit -m "Initial commit"

If you try this and have not configured your global user.email and global user.name, you need to do so:

$ git config --global user.email "your_email_username"
$ git config --global user.name "your_name"

After doing the commit, running git status will show something like this:

$ git status
On branch main
nothing to commit, working tree clean

To view the commits, you can use git log

$ git log
commit 6c3ce8793541efb3bf59566c0c6e476834499eff (HEAD -> main)
Author: vt <vt@yahoo.com>
Date:   Sat Sep 20 20:52:09 2025 -1000

    Initial commit

Now, let’s make some changes to our files. First, let’s change index.html. Here is the new version of index.html

/home/student/Documents/test/index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <script type="module" src="./index.mjs"></script>
  </head>
  <body>
    <h1>Hello</h1>
    <button id="mybutton">Click Me</button>
  </body>
</html>

The new line I added is line 9. Git will help us to track this. Let’s use the git diff command. Here is what you would see if you saved index.html with the changes above:

$ git diff
diff --git a/index.html b/index.html
index 0079105..a691857 100644
--- a/index.html
+++ b/index.html
@@ -6,5 +6,6 @@
   </head>
   <body>
     <h1>Hello</h1>
+    <button id="mybutton">Click Me</button>
   </body>
 </html>

You can see the line with the + is the different line. The git diff command without any arguments will just show the changes between the last commit (HEAD) and the staged area. The last commit is referred to as HEAD and the staged area represents the current state of the files that are not yet committed.

Let’s do our second commit. As a general rule, your commits should be as atomic as is practical. This means that the commit should only be about one thing being changed. In this case we are updating index.html to have a <button>. So, here is our commit command:

$ git commit -m "Added Click Me button to index.html"

If you just ran this, you would see that this did not add do what you wanted, because you need to add index.html. So, the proper steps would have been this:

$ git add index.html
$ git commit -m "Added Click Me button to index.html"

Now, if we run git log this is what you would see:

$ git log
commit 492ad9c8c20d0b2d25718933bbb14902529a4a5f (HEAD -> main)
Author: vt <vt@yahoo.com>
Date:   Sat Sep 20 21:14:43 2025 -1000

    Added Click Me button to index.html

commit 6c3ce8793541efb3bf59566c0c6e476834499eff
Author: vt <vt@yahoo.com>
Date:   Sat Sep 20 20:52:09 2025 -1000

    Initial commit

Now, we have two commits. This will allow us to use git diff to compare the two commits. To do this, you need to enter the first 6 or 7 characters of the commit HASH. So, here is an example of running this command:

$ git diff 492ad9c 6c3ce879
diff --git a/index.html b/index.html
index a691857..0079105 100644
--- a/index.html
+++ b/index.html
@@ -6,6 +6,5 @@
   </head>
   <body>
     <h1>Hello</h1>
-    <button id="mybutton">Click Me</button>
   </body>
 </html>
Again, this identifies the changed line that adds the button.
Let's modify *index.mjs* now.
if (document.readyState === "loading") {
  document.addEventListener('DOMContentLoaded', init);
} else {
  init();
}

function handleClick() {
  console.log('Click Me button was clicked');
}

function init() {
  const mybutton = document.getElementById("mybutton");
  mybutton.addEventListener('click', handleClick);
}

You can see that the highlighted lines, 7-9 and 12-13 have been changed. But, I also deleted the line that used to print 'init called' to the console.

Let’s run git diff to see what it shows:

$ git diff
diff --git a/index.mjs b/index.mjs
index 382cd0d..897bd66 100644
--- a/index.mjs
+++ b/index.mjs
@@ -4,6 +4,11 @@ if (document.readyState === "loading") {
   init();
 }

+function handleClick() {
+  console.log('Click Me button was clicked');
+}
+
 function init() {
-  console.log('init called');
+  const mybutton = document.getElementById("mybutton");
+  mybutton.addEventListener('click', handleClick);
 }

You can see that both the additions and deletions are shown. Let’s commit this.

$ git add index.mjs
$ git commit -m "Modified index.mjs to respond to clicking on Click Me button"

After that, you can run git log again:

$ git log
commit e1ceac5991b2c5ad0dd2a117c0318e23d2e85a5c (HEAD -> main)
Author: vt <vt@yahoo.com>
Date:   Sat Sep 20 21:37:19 2025 -1000

    Modified index.mjs to respond to clicking on Click Me button

commit 492ad9c8c20d0b2d25718933bbb14902529a4a5f
Author: vt <vt@yahoo.com>
Date:   Sat Sep 20 21:14:43 2025 -1000

    Added Click Me button to index.html

commit 6c3ce8793541efb3bf59566c0c6e476834499eff
Author: vt <vt@yahoo.com>
Date:   Sat Sep 20 20:52:09 2025 -1000

    Initial commit

Suppose that I completely messed up one of the files. So, I will delete all the lines in the index.mjs file and save that file. There a number of ways to fix this. Here are some things you can do to revert to an earlier version.

Reverting to an earlier version

Fixing uncommitted mistakes

If you mess up the working branch, but did not commit yet, then you can revert all the files by using the following command:

$ git reset --hard HEAD

Remember that HEAD represents the last commit. So, this will set all the files back to the last commit.

Restoring one file if uncommitted

$ git checkout -- index.mjs

or

$ git checkout HEAD index.mjs

The first command will restore index.mjs to the last committed version and will make it so that the command git diff index.mjs returns no differences. The second command will restore index.mjs to the last committed version and make it so that both git diff index.mjs and git diff --cached index.mjs return no differences. So, the second command clears up the cache too.

I used the first command to restore index.mjs

Undoing most recent commit

If you did commit, and you want to undo that commit, you can run the following command:

$ git revert HEAD

Restoring one file to an earlier commit

Start by using git log to see the HASH sequence for the commit. You only need the first 6 or 7 characters of the HASH. Then, use the following command:

$ git checkout <HASH> index.mjs

Resetting the whole repository to an earlier commit

Find the HASH using git log. Then run the following command:

$ git reset --hard <HASH>

This will make HEAD point to the specified <HASH>, resets the staging area, and resets the working directory. Any changes you had staged or any uncommitted changes are permanently discarded. So, this is quite a destructive operation and should only be done if necessary.

Using a cloud repository, GitHub

Although there are several cloud-based Git repositories, GitHub (GitHub Docs) is probably the best for individual developers and developers that work in a group for some project. BitBucket is made more for companies that have Git repository needs. Although you could use GitHub or BitBucket as a programmer, we will stick to GitHub for our lessons. This is partly because GitHub integration is part of the CodeSandbox setup, and partly because GitHub is so popular.

To get a GitHub account you can go to the following site: github.com. Enter your email address and click on the Sign up for GitHub button.

github signup

Choose a password and username, or sign in with Google if that is an option for you. Be sure to store your password in a secure location like a password saver. Then, create your account.

Generating SSH keys

Here is a link from the GitHub documentation on generating a SSH key and using it for authentication on GitHub: GitHub Docs - Generating a new SSH key and adding it to the ssh-agent

Start by going to a terminal on your local machine and run the following command:

$ ssh-keygen -t ed25519 -C "your_email@example.com"

Substitute in you actual email address. You will get a message saying that the program is generating a public/private key pair. When it asks where you want to save the key, the default location is usually a good place. But, you should take note of where it is saving it. If you choose a passphrase, make sure that you save this passphrase in a secure location.

Once you have more than one repository, using the ssh-agent and using the ssh-add command as shown next, is a crucial step. This is because GitHub expects that you have a different set of SSH keys for each repository. This means you will have to create additional SSH keys for each repository you want to connect to on GitHub. You can use names that help you to remember which set of keys goes with a repository. When you add a Deploy key for the repository on GitHub, GitHub still needs to know which SSH keys to use. This is the purpose of running ssh-agent and the ssh-add command.

Next, you want to add your SSH key to the ssh-agent.

$ eval "$(ssh-agent -s)"

A message showing the pid (Process ID) will show up, as ssh-agent is now running in the background. Next you need to add your SSH private key to the ssh-agent.

ssh-add <location_of_your_private_key_file>

By default on Linux, the location of the private key file is ~/.ssh/id_ed25519. If you stored it somewhere else and/or gave it a different name, you should adjust accordingly. You will be prompted to enter your passphrase that you created when running ssh-keygen.

Finally, you need to add your SSH key from your local machine to your GitHub account. Start by running the following command, and copying the output to your clipboard:

$ cat ~/.ssh/id_ed25519.pub

Select and copy the contents of that file. Then, on your GitHub account, go to your repository and click on Settings

settings repository

This will bring up a menu on the left side. Scroll down to the Security area and select Deploy keys.

deploy keys

This will bring up an area where you can click on the green Add deploy key button.

add deploy key

Then, paste your key into the window. Describe your key so you can distinguish it from other keys. Then, make sure that you check the Allow write access box, so that you can push remotely to this repository.

add key with write

Creating the remote repository on GitHub

Login to GitHub and click on Create Repository in the left sidebar:

button create repository

Give the Repository a name. Making the name descriptive will help you to keep track of your repositories. I named my repository test, because this was just for demo purposes. Set the visibility to Private. The, click on Create repository.

Assuming you have already set up the SSH keys, navigate your terminal to the location of your local Git repository. Then, enter the following command:

$ cd ~/Documents/test
$ git remote add origin git@github.com:<username>/<project_name.git>

For <username> substitute in your GitHub username. For <project_name.git>, substitute in your project name followed by git. So for me, this would have been test.git. So, if your username was web-coder01, you would enter:

$ git remote add origin git@github.com:web-coder01/test.git

Once this is done, you can push your local repository up to GitHub. You should use git status to check to see that your local repository has nothing to commit (up to date).

$ git status
On branch main
nothing to commit, working tree clean

If nothing to commit, note the branch you are on then run the following, where main is the name of your branch

$ git push origin main
The authenticity of host 'github.com (140.82.116.3)' can't be established.
ED25519 key fingerprint is SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'github.com' (ED25519) to the list of known hosts.
Enumerating objects: 10, done.
Counting objects: 100% (10/10), done.
Delta compression using up to 12 threads
Compressing objects: 100% (10/10), done.
Writing objects: 100% (10/10), 1.11 KiB | 378.00 KiB/s, done.
Total 10 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), done.
To github.com:takebayashiv-cmd/test.git
 * [new branch]      main -> main

Enter yes to the prompt. You can now look at your repository and see your files.

test repository files

Windows 11 - generating SSH key and pushing to GitHub

On Windows, you start by starting up the Git Bash app. If you have not added this to your Taskbar, use the Search next to the Start button and type 'Git Bash' to locate the app. Right-click on this and pin it to the Taskbar if you have not already done so. Open up Git Bash. I have right-clicked on the title bar for that window and selected Options.

options git bash start

In the options on the Looks menu I changed the Background color to white and the Foreground color to black and then hit Apply. Then I went to the Text menu and changed the font size to 14pt. That is why my Git Bash window has the appearance shown in the screen shot above.

Here is a screen shot showing the commands that I entered in Git Bash:

commands git bash

As you can see, Git Bash will start up in your home directory. The pwd command shows the working directory to be your home directory. I then changed into the directory that has our local Git repository, ~/Documents/test.

Let’s generate the SSH keys

$ ssh-keygen -t ed25519 -C <your_email>

When you see the default location and name for the SSH keys, you can accept this. But, if you are creating more than one key (as you will need to if you will have more than one repository), you should choose the name. For example, I did this:

Enter file in which to save the key (/c/Users/student/.ssh/id_ed25519): /c/Users/student/.ssh/win11_extra

This wrote my keys to /c/Users/student/.ssh/win11_extra.

Next, you go to your GitHub account and select the repository you have created. Go to Settings and click on Deploy keys. On your local computer, run the following command to get your pub key:

$ cat /c/Users/student/.ssh/win11_extra.pub

Select that public key and right-click and choose Copy. Then, on GitHub click on Add Deploy key, and paste your key into the Key box. Add an appropriate title. Make sure that you check the box giving write privileges. Otherwise you can’t push to GitHub.

Substitute in the name you used to save the public key with for win11_extra.pub. You should see that the key has been saved. Remember, you cannot use this same key for other repositories. You need to generate SSH keys for each repository you want to connect to on GitHub.

Go back to your local computer, and check git status to make sure that you are on branch main and there is nothing to commit. Then, we need to use ssh-agent to run the ssh-add command:

$ eval $(ssh-agent -s)
Agent pid 448

You should see that a pid (process id) is shown.

Next, you use the ssh-add command and add your private key:

$ ssh-add /c/Users/student/.ssh/win11_extra

Note this is the private key, so there is no .pub on the end. Also, substitute in the name you actually used. You should get a message saying that the Identity was added. You can also double check by running this command:

$ ssh-add -l

This will list any keys that have been added.

Now, you are set to push to GitHub. Run the following commands:

$ git remote add origin git@github.com:<username>/<repository_name.git>
$ git push -u origin main

Substitute in your GitHub username and repository name for the above command.

> cd ~
> mkdir .ssh
> ssh-keygen -t ed25519 -C <your_email>

You can save to the default location: C:\Users\student/.ssh/id_ed25519
Remember to replace student with your username on Windows.

Add the public key to your GitHub repository. As shown above, this means going to SettingsDeploy keys, and copying and pasting the public key that you just created. On Windows, you can display the public key by running this command:

MacOS - generating SSH key and pushing to GitHub

% ssh-keygen -t ed25519 -C <your_email>

By default, this will store the keys in /Users/student/.ssh/id_ed25519

Note that you should change the name if you are going to use more than one GitHub repository. You should have a set of SSH keys for each repository.

Add the public key to your GitHub repository. As shown above, this means going to SettingsDeploy keys, and copying and pasting the public key that you just created. On MacOS, you can display the public key by running this command:

% cat ~/.ssh/id_ed25519.pub

Next, you need to run ssh-agent so that you can use the ssh-add command to add the matching key to the one you just added to the GitHub repository.

% eval $(ssh-agent -s)
Agent pid 4226
% ssh-add ~/.ssh/id_ed25519

Note that you should substite the key name if your key name is different. Also, note that this is the private key so there is no .pub at the end of the filename.

You should see Indentity added:. You can also double check by running this command:

% ssh-add -l

This will list any keys that have been added.

Next, run git status to make sure the repository is up to date

% git status On branch main nothing to commit, working tree clean

Add the remote origin, and push up to GitHub.

% git remote add origin git@github.com:<username>/<project_name.git>
% git push origin main

Pulling from GitHub

If you are setting up a local repository by pulling from GitHub, you need to make sure you generate SSH keys and deploy those keys on your GitHub project repository. If you already have generated SSH keys, you can copy and paste the public key when you deploy a key for that project. Then, you can use the following command:

$ git remote add origin git@github.com:<username>/<project_name.git>
$ git pull origin <branch_name>

If you have already connected to the GitHub repository, you can just use the git pull origin <branch_name> command.

CodeSandbox

If you are using a CodeSandbox sandbox, there is no good way to link this with a GitHub repository. Only CodeSandbox devboxes are made to link with GitHub. Since a devbox will use resources that a sandbox does not, this does limit the use of devboxes if you are using a free account on CodeSandbox. So, for the early lessons where you are just using a sandbox, you can copy your files to your local computer and at least have some sort of backup.

CodeSandbox - Devboxes

For some of the later lessons, we will be making use of devboxes instead of sandboxes. These are lessons that make use of a backend database. So, here is how you can utilize GitHub with a CodeSandbox devbox.

If you logged in to CodeSandbox with a GitHub account, then linking any devbox to your GitHub repository will be already established. So, I will go over how to link to GitHub assuming you used a Google account.

Once you are logged in to CodeSandbox, create a devbox. Click on the + Create button at the top right of the window near the button for your User settings. Click on the Server templates and select the Node.js template.

nodejs devbox

This will bring up a box to configure your devbox. Give your devbox a name like "node.js_test", and click Create Devbox. Note that this is a Devbox, not a Sandbox.

node.js configure

This will cause the Devbox to be created. Here is what you would see:

devbox node.js test1

Note that for Devboxes, a terminal is present. You can use this terminal to run commands for this workspace. Next, click on the package.json file in the Explorer. Here are the contents:

package.json
{
  "name": "nodejs-sandbox",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node --watch index.js"
  },
  "keywords": [],
  "author": "Ives van Hoorne",
  "license": "MIT",
  "devDependencies": {},
  "dependencies": {}
}

Note that the "main" key is set to index.js. This names the file that will be run by default. If you look at the "scripts" key, that is set to "node --watch index.js". This command was actually run in the terminal if you look carefully. The --watch means that the workspace will update if you make changes to index.js.

If you click on index.js in the Explorer, you will see that it consists of just one line:

index.js
console.log("Hello CodeSandbox");

If you look in the Terminal, you will see this output:

devbox running index.js

Now that you have a running Devbox, log in to your GitHub account in a different window and create a GitHub project to serve as the repository for this devbox. In the drop-down list for the + on the top right, select New repository

github new repositor

Change the name of the project to match the name of your CodeSandbox devbox. If you can’t get the exact same name, just get it close enough so you can recognize which GitHub project should be linked to your CodeSandbox devbox. Make the repository private, then click on Create repository.

node.js repository

With your GitHub repository set up, go back to your CodeSandbox. Go back to your Dashboard and click on your user button in the top right corner and select User settings:

user settings

The User settings box will have a menu on the left. Click on the Integration menu. This will bring up a box that has a drop-down where you can click on labelled Authorize access to all repositories. You can switch to just get Authorize access only to public repositories, but the first choice is what we want.

authorize access choice

This will bring you to the Sign in to GitHub box:

sign in github

Either enter your GitHub username and password, or if you are using your Google account to sign in to GitHub, click on the Continue with Google. When you are signed in, you will see that the links to your GitHub account have been added:

repositories integrated

Now that these links have been created, you can open up your devbox and click on the additional menus ellipsis and select Export to GitHub.

export to github

This will bring up a box that has a button Export to GitHub that you click on.

create github repository

The repository created earlier is recognized and you just click Create repository.

create repository actual

Now you can make a change to your code. Here I added a second line of console.log output to index.js. Then, you click on the Source control button on the left. Hover the mouse to the right of the file that is changed and click on the + sign.

source changes

Clicking the + symbol will stage the commit. This will allow you to enter a message for the commit above the Source control area. After entering your message, click on the Commit button.

modified console statement

This will bring up the Sync Changes button:

sync

It will take a little while to set up the sync and then a message asking if it is okay to push to origin/main. Click OK.

ok to push

Here is a screen shot on my GitHub account that shows the changes have been saved.

changes github shown

CodeSandbox - Sandbox and GitHub

As mentioned earlier, there is no good way to sync your CodeSandbox sandbox with GitHub. It is possible to use GitHub as a version control, but it requires multiple manual steps. This is not recommended, but if you want to attempt this, here is an outline of the steps.

  • For your first export (initial upload)

    • Work in CodeSandbox: Create and edit your files within your CodeSandbox sandbox.

    • Download the project: When you are ready to save your work, go to the file menu (often a folder icon or file icon in the top-left) and select "Download as ZIP".

  • Create a GitHub repository: In a new browser tab, go to github.com and create a new repository for your project. Do not add a README or any files yet.

  • Upload initial files:

    • Once the empty repository is created, click the "upload files" link.

    • Unzip the file you downloaded from CodeSandbox.

    • Drag and drop the contents of the unzipped folder into the upload box on GitHub.

    • Commit the changes: Add a commit message (e.g., "Initial commit") and click "Commit changes" to upload the files to your repository’s main branch.

  • For subsequent updates (using pull requests)

    • Download updated files: After making more changes in CodeSandbox, download another ZIP file.

    • Create a new branch: On your GitHub repository page, click the branch selector (it likely says main). Type a name for a new, descriptive branch (e.g., feature/new-contact-form) and press Enter.

  • Upload files to the new branch:

    • Ensure your newly created branch is selected in the branch selector.

    • Click "Add file" > "Upload files".

    • Drag and drop the updated files from your unzipped CodeSandbox download.

    • Add a commit message and confirm you are committing to the new feature branch.

  • Create a pull request (PR):

    • After uploading, a yellow banner should appear at the top of the repository page saying your new branch has been pushed. Click the "Compare & pull request" button.

    • Alternatively, go to the "Pull requests" tab and click "New pull request".

    • Select your feature branch as the "compare" branch and main as the "base" branch.

  • Review and merge the PR:

    • Add a title and description for your pull request.

    • Click "Create pull request".

    • Review the file changes listed in the PR interface.

    • Click the green "Merge pull request" button to merge your changes into the main branch.

  • How to use this workflow effectively

    • Make small changes: Complete a small, logical chunk of work in your CodeSandbox before downloading and pushing to GitHub. This makes each pull request focused and easy to review.

    • Use descriptive branch names: Name your branches clearly (e.g., add-login-button, fix-css-bug) to keep a clean, understandable history.

    • Always use branches: Do not upload and commit directly to the main branch. Creating a new branch for each set of changes is crucial for preserving a proper version history via pull requests. Otherwise, you will simply overwrite the earlier branch and you will have lost the original commit.