RMIT University

COSC2767 · Systems Deployment and Operations

Week 3: Git and AWS Lab Guide

Use Git for local and remote version control while creating and managing cloud resources in AWS.

🎯 Objective

Week tutorial screenshot from page 1

In this lab, we have two main objectives:

  • Revise what we have learned about the version control GIT and remote repository on Github.

  • Get familiar with Amazon Web Services on the leaner lab and learn how to create AWS EC2 instances.

Screenshot illustrating instances.

☁️ AWS Academy and your first EC2 instance

AWS Academy Learner Lab offers a long-running lab environment suitable for student projects over a period designated by the educator.

Each student in an AWS Academy Learner Lab class will have a $50 AWS Platform Credit to use for the duration of the class.

Each session lasts for 4 hours by default, although students can extend a session to run longer by pressing the start button to reset their session timer. At the end of each session, any resources students create will persist. However, we automatically shut EC2 instances down. Other resources, such as RDS instances, keep running. Keep in mind that we do not stop some AWS features, so they can still incur charges between sessions.

Students may wish to delete those types of resources and recreate them as needed to test their work during a session. Students will have access to this environment for the duration of the class they enrolled you in. When the class ends, student access to the learner lab will also end.

This guide provides you with instructions on how to use AWS Academy Learner Labs. These instructions apply to both AWS Academy Learner Lab – Foundational Services and AWS Academy Learner Lab – Association Services. This guide covers setting up and logging into your AWS Academy Account, accessing your Learner Lab, and using your Learner Lab.

Set up and sign in to AWS Academy

Screenshot illustrating Setting Up and Logging Into Your AWS Academy Account
  • Set up your AWS Academy account by responding to your email invitation and clicking Get Started. The email invitation will come from AWS Academy <notifications@instructure.com>. If you do not see the email, check your junk, spam, or promotional mail folder. Here is a sample invitation email:

Screenshot illustrating see the email, check your junk, spam, or promotional mail folder. Here is a sample invitation email:
Screenshot illustrating Use the email address that received the email invitation for the email field.

Open the Learner Lab

  • In the AWS Academy Dashboard, click on the Learner Lab you wish to use. Students invited to more than one course/learner lab will see multiple tiles on the dashboard.

Screenshot illustrating more than one course/learner lab will see multiple tiles on the dashboard.
  • Select Modules.

Screenshot illustrating Select Modules.
  • Select the Learner Lab item.

Screenshot illustrating Select the Learner Lab item.

Use the Learner Lab

  • The instructions for using the lab environment are to the right of the console window. You can return to the instructions by pressing the Readme button. The instructions include important details about how to access and use your AWS account, the AWS Services available to you, and the restrictions placed on some AWS Services.

Screenshot illustrating restrictions placed on some AWS Services.
  • Start the lab by selecting Start Lab.

Screenshot illustrating Start the lab by selecting Start Lab.
  • When the dot next to AWS turns yellow , your lab environment is still being prepared to use. So wait for it!

Screenshot illustrating wait for it!
  • When the dot next to AWS turns green , your lab environment is ready to use . Click AWS to launch the AWS Console in a new tab.

Screenshot illustrating the AWS Console in a new tab.
  • A new tab will open the AWS Management Console when you click on AWS. The system logged you into a temporary AWS account and the lab session will automatically end when the session timer expires. The system will save your work when you end the session or the session timer expires.

    • Note: The system will suspend your EC2 instances at the end of a session and they will restart when you start the lab again. Press Start if you need to start up a new lab session.

Screenshot illustrating restart when you start the lab again. Press Start if you need to start up a new lab session.
  • Alternatively, you can use the terminal window to the left of the instructions to use the AWS Command-Line Interface (CLI) to interact with your account.

Screenshot illustrating Command-Line Interface (CLI) to interact with your account.
  • Return to the AWS Academy LMS tab to view the lab instructions or to control your lab session.

Screenshot illustrating Return to the AWS Academy LMS tab to view the lab instructions or to control your lab session.
  • To monitor spending, see the area at the top of the lab instructions. Note: This information is provided by the AWS Budgets service and might be delayed by up to 8 hours. This is an approximate view of spending.

    • Note: If you spend the entire budget, you will lose all of your work, and the system will deactivate your temporary AWS account. Your $50 budget is sufficient for most academic projects, as long as you take care to stay within the budget guidelines.

Screenshot illustrating projects, as long as you take care to stay within the budget guidelines.
  • You can monitor your remaining session time at the top of the lab. Note: If you are actively working and you need more time, you can reset your session timer by pressing Start Lab again.

Screenshot illustrating working and you need more time, you can reset your session timer by pressing Start Lab again.
  • To delete all resources that you have configured in a lab and start with a fresh AWS account, choose Reset . Important: All work will be lost and cannot be recovered.

    • This option will not reset your budget. Any spending that you have incurred will continue to be tracked.

Screenshot illustrating to be tracked.
  • When you are finished with the session, choose End Lab .

    • Any running Amazon Elastic Compute Cloud (Amazon EC2) instances will be stopped. If you return and restart the lab, any stopped EC2 instances will restart and any other resources that you configured will still be available.

    • Important : If you created and started other AWS resources such as a NAT gateway or Amazon Relational Database Service (Amazon RDS) database, those resources will continue to run in the background and incur charges, even outside of your lab session time.

[Important Note] Due to an AWS Learner Lab policy, our AWS lab environment is restricted to only us-east-1 and us-west-2 regions. Therefore, please make sure to select either one of these regions when you start your lab exercises.

Screenshot illustrating you start your lab exercises.

Create your first EC2 instance

  • First, let's open the AWS console:

Screenshot illustrating First, let's open the AWS console:
Screenshot illustrating First, let's open the AWS console:
Screenshot illustrating First, let's open the AWS console:
  • Here are the settings of our new EC2 Linux instance:

Screenshot illustrating Here are the settings of our new EC2 Linux instance:
  • Choosing the default AMI of AWS (Amazon Linux 2023) is the best to run on EC2 instances. Indeed, this AMI of AWS is based on a version of RHEL (Red Hat Enterprise Linux) - Fedora . Amazon has customised it to suit AWS environments, optimising it for cloud use with packages, settings, and configurations tailored to improve performance, security, and compatibility with AWS services

Screenshot illustrating services
  • Since the purpose of our project is learning, so let's stick with the small and sufficient instance type (hardware):

    • The t3.micro is a low-cost Amazon EC2 instance with 2 vCPU and 1 GB RAM, ideal for lightweight workloads. It offers burstable performance using a CPU credit system, making it suitable for small web servers, testing, and development.

Screenshot illustrating it suitable for small web servers, testing, and development.
  • Create a new key pair to securely SSH to your EC2 instance:

Screenshot illustrating Create a new key pair to securely SSH to your EC2 instance:
Screenshot illustrating Create a new key pair to securely SSH to your EC2 instance:
  • Now the browser should download a devops_project_key.pem to your computer. Please keep this file safe (as we will try to use only one key for all of our EC2 instances in this course):

Screenshot illustrating file safe (as we will try to use only one key for all of our EC2 instances in this course):
  • Now, our EC2 instance will use that new SSH key “devops_project_key" as a way for us to pass authentication and login to the EC2 instance using the key.

Screenshot illustrating authentication and login to the EC2 instance using the key.
  • We need to create a security group (firewall rules) to secure and protect our VMs:

Screenshot illustrating We need to create a security group (firewall rules) to secure and protect our VMs:
Screenshot illustrating We need to create a security group (firewall rules) to secure and protect our VMs:
  • The default 8 GB for storage is plenty enough for our EC2 server:

    • gp3 is a type of Amazon EBS (Elastic Block Store) SSD storage used with EC2 instances. It offers faster performance and lower cost than the older gp2. With gp3, you get 3,000 IOPS by default, and you can increase speed without changing the storage size. It’s great for things like boot volumes, apps, and small databases.

Screenshot illustrating things like boot volumes, apps, and small databases.
  • After that, review the configuration settings and launch the instance:

Screenshot illustrating After that, review the configuration settings and launch the instance:
  • AWS will announce that it has started to create a new EC2 instance based on your configuration:

Screenshot illustrating AWS will announce that it has started to create a new EC2 instance based on your configuration:
Screenshot illustrating AWS will announce that it has started to create a new EC2 instance based on your configuration:
Screenshot illustrating AWS will announce that it has started to create a new EC2 instance based on your configuration:
  • In the EC2 dashboard you should see the git-devops EC2 running:

Screenshot illustrating In the EC2 dashboard you should see the git-devops EC2 running:
  • You can check out all related information about your EC2 instance here. The most important information is the Public IP address of your EC2 instance which will allow us to connect SSH to the server to control it:

Screenshot illustrating server to control it:
  • Now we will use the SSH key to SSH to the EC2 instance, there are different instructions for different operating systems of your laptop (Windows 10, 11, MacOS or Linux):

    • [For Windows 10 or 11 users], you can try to SSH using Powershell or Command Prompt (cmd). These instructions are for Windows 10 or 11 users only:

      • Open PowerShell as Administrator

Screenshot illustrating Open PowerShell as Administrator
  • You can check whether OpenSSH Client is already installed:

ssh -V
Screenshot illustrating ssh -V
  • If SSH is not yet installed, then install it if need:

    • Windows 10: Settings → Apps → Optional Features

      • Windows 11: Settings → System → Optional features

        • Search for OpenSSH Client

        • Select it and click Install

Screenshot illustrating Select it and click Install (1 of 3)Screenshot illustrating Select it and click Install (2 of 3)Screenshot illustrating Select it and click Install (3 of 3)
  • Reopen PowerShell to check if SSH is already installed:

Screenshot illustrating Reopen PowerShell to check if SSH is already installed:
  • Next, please change the current directory into where you store that ssh pem file key. (you can use “cd”). Try to copy the example SSH command from AWS EC2:

    • ssh -i path_to_ssh_key username@ip-or-domain-name-of-host

      • Here is example:

ssh -i "devops_project_key.pem" ec2-user@ec2-18-212-255-237.compute-1.amazonaws.com
  • SSH is working now, you've just hit the "permissions too open" error, which is the expected next step. The key file needs its permissions locked down so only your user can read it.

Screenshot illustrating user can read it.
  • Run these two commands in PowerShell as the Administrator :

    • /reset clears the custom entries back to inherited defaults.

      • /inheritance:r then removes all inherited permissions (this is what strips out Authenticated Users, Users, Administrators, and SYSTEM).

        • /grant:r adds back read access for just your account.

icacls "devops_key.pem" /reset
icacls "devops_key.pem" /inheritance:r
icacls "devops_key.pem" /grant:r "$($env:USERNAME):(R)"
Screenshot illustrating icacls "devops_key.pem" /reset icacls "devops_key.pem" /inheritance:r icacls "devops_key.pem" /grant:r "$($env:USERNAME):(R)"
  • To verify only your user is listed afterward:

    • That's exactly what you want below, only your_username:(R) and nothing else. The key is now properly locked down.

icacls "devops_key.pem"
Screenshot illustrating icacls "devops_key.pem"
  • Try to SSH to EC2 again:

Screenshot illustrating Try to SSH to EC2 again:
  • [For older Windows users (Windows 8, 7 or XP)], you can try to SSH using Putty or Mobaxterm. These instructions are for older Windows users only:

    • You will use PuTTY to SSH to Amazon EC2 instances. If you do not have PuTTY installed on your computer, download it here.

      • Open putty.exe

      • Configure PuTTY to not timeout:

        • Choose Connection

        • Set Seconds between keepalives to 30

      • This allows you to keep the PuTTY session open for a longer period of time.

      • Configure your PuTTY session:

        • Choose Session

        • Host Name (or IP address): Copy and paste the IPv4 Public IP address for the instance.

      • Back in PuTTy, in the Connection list, expand SSH

        • Choose Auth (don't expand it)

        • Choose Browse

        • Browse to and select the .pem file that you downloaded

        • Choose Open to select it

        • Choose Open

      • Choose Yes, to trust the host and connect to it.

      • When prompted login as, enter: ec2-user

      • This will connect you to the EC2 instance.

    • [For MacOS and Linux (like Ubuntu) users], we just need to use Terminals:

      • Open a terminal window, and change directory cd to the directory where the .pem file was downloaded. For example, run this command, if it was saved to your Downloads directory:

cd ~/Downloads
  • Change the permissions on the key to be read only, by running this command:

chmod 400 devops_project_key.pem
  • To keep it easy, we gonna ask AWS to show us the command to SSH to the instance, and copy that command:

Screenshot illustrating instance, and copy that command:
Screenshot illustrating instance, and copy that command:
  • Run that command in the terminal:

ssh -i "devops_project_key.pem" ec2-user@ec2-18-212-255-237.compute-1.amazonaws.com
  • Note: make sure you copy that command from AWS since the Public DNS will be different for each EC2 instances.

    • The first time you connect to your EC2 instance, you need to type “yes” to add that new SSH connection to known hosts:

Screenshot illustrating that new SSH connection to known hosts:
  • After that, you should SSH successfully to the remote EC2 Server like below:

Screenshot illustrating After that, you should SSH successfully to the remote EC2 Server like below:
  • Now you can treat this as the usual Fedora VM or CentOS VM, we have been dealing with so far in week 1 and 2. However, the difference is that this VM is actually a cloud server running on a remote Amazon data centre.

  • You can play around with CLI commands you learn so far, for example:

Screenshot illustrating You can play around with CLI commands you learn so far, for example:
Screenshot illustrating You can play around with CLI commands you learn so far, for example:

Suggestion : you should move your SSH key to a more secure folder like ~/.ssh/keys so you remember where your SSH key is for the next time you want to SSH to the EC2 instance!

📘 Intro to Version Control

Screenshot illustrating 2. Intro to Version Control

Github, in a nutshell, is the way to share files with other people collaboratively without overwriting other people's stuff. Github is sort of a community, and there are a lot of open-source projects, which means the project's code is available to look at. Github is a web-based platform, and it is based on a technology called Git.

Git is a piece of software called version control. It is a fancy way of saying Keeps track of changes to code. Git has a lot of other features that are useful for software developers. So if you're programming, eventually you have to learn Git at some point.

Optional: Practise Git with Learn Git Branching

Playground

This exercise will help you learn the basics and some advanced features of Git and GitHub. You'll use the interactive platform LearnGitBranching for hands-on practice.

Version control concepts

  1. Getting Started:

    • Go to LearnGitBranching and click "Start Learning" or "Sandbox".

    • Choose your language if asked.

  2. Complete Main Module Exercises:

    • Start with the Introduction Sequence in the Main module to learn fundamental Git commands.

    • Continue with the Ramping Up section to explore more about branches and how to reorganize them with rebase.

  3. Move to Remote Module Exercises:

    • After finishing the Main module, go to the Remote module.

    • Complete the exercises in Push & Pull -- Git Remotes! to learn how to connect and work with remote repositories.

  4. Tips for Using LearnGitBranching:

    • Follow the instructions for each exercise.

    • Use the visuals to see how your actions affect the Git tree.

    • If stuck, use the "Hint" button for tips.

  5. Learning Goals:

    • Get comfortable with basic Git operations.

    • Understand how to manage branches and handle merges.

    • Learn how to push to and pull from remote repositories effectively.

Ideally, try your best to finish these recommended exercises:

Screenshot illustrating Ideally, try your best to finish these recommended exercises:
Screenshot illustrating Ideally, try your best to finish these recommended exercises:

Finish all the exercises to improve your understanding of Git and GitHub. Feel free to share your experiences or questions with others. This knowledge is essential for working on software development projects.

Screenshot illustrating development projects.

☁️ Git practice on AWS EC2

To start, please:

  • Ready to play around with CLI commands in the challenges below on the AWS instance:

🧪 Challenge 0: Explore a local Git repository

  • Incase this AMI image on your AWS EC2 instance does not have Git, we can install Git command:

sudo yum install git -y

Question: why do we need to have “sudo” and “-y”?

Screenshot illustrating Question: why do we need to have “sudo” and “-y”?
  • Enter your git information for the local repository (only need to do once)

    • Explanation :

      • The commands git config --global user.email "you@example.com" and git config --global user.name "Your Name" set your email and name as the default identity for all your Git commits on that computer.

      • The --global option applies these settings across all Git repositories you work with on that machine. Replace "you@example.com" and "Your Name" with your actual email and name.

git config --global user.email "you@example.com"
git config --global user.name "Your Name"
Screenshot illustrating git config --global user.email "you@example.com" git config --global user.name "Your Name"
  • Create a new folder so we can work on

mkdir my_project
  • Change current working directory to that my_project directory

cd my_project
  • List all files and folders (including hidden ones -a and in long format -l)

ls -la

Question: what directories do you see in this empty directory?

Screenshot illustrating Question: what directories do you see in this empty directory?
  • Initialize the git folder

git init
Screenshot illustrating git init

You will see some hints from Git, but you can safely ignore it! Long story short, it tries to tell you that the default main branch name is “master”. However, the default main branch in other remote repositories, like Github, is “main” instead of “master”.

Question: Could you guess why they prefer the name “main” instead of “master” based on the history of America? Hint : political reasons.

  • Let’s respect the culture and change the current branch to be “main” from master:

git branch -m main
  • Also, to keep thing simple, we set the default branch will be “main” from now on for future new git repository:

git config --global init.defaultBranch main
  • List all files and folders again (including hidden ones -a and in long format -l)

ls -la

Question : Do you notice any special folder?

Screenshot illustrating Question : Do you notice any special folder?
  • Check current status of git

git status

Question : What does git status tell you ?

Screenshot illustrating Question : What does git status tell you ?
  • Check log of all the git commits

git log

Question : What does it try to tell you?

Screenshot illustrating Question : What does it try to tell you?
  • That's cool. You have made your first git commit! Let's add more files!

touch file2.py
touch file3.py
echo 'print("Hello")' >> file2.py
echo 'print("Bonjour")' >> file3.py
  • Check current status of git again

git status

Question: Can you figure out what it means by “untracked files”?

Screenshot illustrating Question: Can you figure out what it means by “untracked files”?
  • Let git track that new file for changes (Staged)

git add .

Question: What does . means this time? And what does “git add” try to do?

  • Check current status of git again

git status

Question: Do you still see “untracked files”? Why or Why not?

Screenshot illustrating Question: Do you still see “untracked files”? Why or Why not?
  • You are happy with these changes and want to finalize your change and really commit to the change!

git commit -m "Two more python files are added"
Screenshot illustrating git commit -m "Two more python files are added"

Question : what does “git commit” try to do? What does “-m” do?

  • Check current status of git again

git status

Question : What do you see changed this time?

  • Check the history of all commits

git log

Question : Do you see your commit and its message?

Screenshot illustrating Question : Do you see your commit and its message?
  • Check the names of all branches:

git branch -a

Question : Can you see how many branches you have and what is your current branch ?

Screenshot illustrating Question : Can you see how many branches you have and what is your current branch ?
  • Create a new branch new_feature

git branch new_feature

Question : Why do we need to create another branch? How about we just always work on the main branch?

  • Check the names of all branches again:

git branch -a

Question : Can you see how many branches you have and what is your current branch ?

Screenshot illustrating Question : Can you see how many branches you have and what is your current branch ?
  • Switch to that new branch “new_feature”:

git checkout new_feature
  • Check the names of all branches again:

git branch -a

Question : Do you see your current branch has changed to the new branch “new_feature” ?

Screenshot illustrating Question : Do you see your current branch has changed to the new branch “new_feature” ?
  • That's cool. You have made your first branch! Let's add more files to that branch!

touch file4.py
touch file5.py
echo 'print("cam on")' >> file4.py
echo 'print("thank you")' >> file5.py
  • Check current status of git again

git status
Screenshot illustrating git status
  • Let git track that new file for changes (Staged)

git add .
  • Check current status of git again

git status
Screenshot illustrating git status
  • Finalize your change and really commit to the change (Committed)

git commit -m "New files are added on the new branch"
  • Check current status of git again

git status
Screenshot illustrating git status
  • Check log of all the git commits

git log
Screenshot illustrating git log
  • Switch back to main branch

git checkout main
Screenshot illustrating git checkout main
  • List all files again:

ls -la

Question: Can you see what has changed at the moment you switch back to the main branch from new_feature branch? Is there any file missing? Why is that?

Screenshot illustrating new_feature branch? Is there any file missing? Why is that?

Question: What will happen if you switch back to new_feature branch from the main branch?

  • Hint: what happens to file4.py and file5.py ?

  • Switch back to that new_feature branch

git checkout new_feature

Question: Can you see what has changed you expected?

Screenshot illustrating Question: Can you see what has changed you expected?
  • Switch back to that main branch

git checkout main
  • If you are happy with what is on the new_feature branch, let's merge it to the main branch!

git merge new_feature
Screenshot illustrating git merge new_feature
  • See what is on the git log on the main branch

git log
Screenshot illustrating git log
  • Let's add some new files and content to main branch

touch file6.py
echo "This is pretty new content" >> file6.py
  • See what is on the git log on the main branch

git status
  • Let's track it (stage) and commit it

git add .
git commit -m "added file6.py"
  • Now, you switch back to new_feature branch

git checkout new_feature

Question : you are back to the new_feature branch, what will happen to file6.py ?

  • Now, if we want the new content of main branch to be on new_feature branch, we need to merge main branch back to new_feature branch

git merge main
Screenshot illustrating git merge main

That's pretty much the basic local Git!

  • If you want to check the compact (shorter and neat) version of git log then run this command:

git log --graph --decorate --oneline

Question : Does it look cleaner for you?

Screenshot illustrating Question : Does it look cleaner for you?

Remember these commands on local Git:

  • git init

  • git status

  • git add .

  • git commit -m "xxx"

  • git log

  • git branch -a

  • git branch my_new_branch

  • git checkout my_new_branch

  • git merge other_branch

🧪 Challenge 1: Work with a remote GitHub repository

Screenshot illustrating Challenge 1: Git Commands Exercises for Remote Git on GitHub Repository

Now time to move online to practise Git commands on actual Github repositories!

How to setup a new Github repository

Step 1: Create a GitHub repository

  • Go to https://github.com/

  • In the upper-right corner of any page, use the drop-down menu, and select New.

Screenshot illustrating In the upper-right corner of any page, use the drop-down menu, and select New.
  • Type a short, memorable name for your repository. For example, "my_new_project".

Screenshot illustrating Type a short, memorable name for your repository. For example, "my_new_project".
  • Optionally, add a description of your repository. For example, "Learning DevOps at RMIT"

Screenshot illustrating Optionally, add a description of your repository. For example, "Learning DevOps at RMIT"
  • Choose public visibility (Anyone can see, and checkout your github repository).

Screenshot illustrating Choose public visibility (Anyone can see, and checkout your github repository).
  • Untick to initialise this repository without a README file to keep things simple when we push it! However, later on, it is important to add a README file which is important if you want other people to understand what and how to use your project.

Screenshot illustrating people to understand what and how to use your project.
  • For a licence: Since we are learning so we can skip this and choose None! However, later on if you are doing a serious project then it’s better to add a licence so other people on the internet will know how much you are willing for them to reuse parts of your code! The default good one is “MIT License” which is meant to be extremely straightforward and open. It permits users to do anything with a given project as long as they credit the developer and don't hold him or her liable for the project's use.

Screenshot illustrating for the project's use.
  • Click Create repository.

Screenshot illustrating Click Create repository.

Step 2: Connect the local repository to GitHub

  • Note: You can find the HTTPs URL of your Github repo here:

Screenshot illustrating Note: You can find the HTTPs URL of your Github repo here:
  • Here are two ways for you to get started with a Github repo:

    • Option 1 (Recommended in this lab): Push an existing repository from the command line

git remote add origin https://github.com/your_github_name/your_git_repo_name.git
git push -u origin main
  • Option 2 (Recommended in other cases): Create a new repository on the command line

git clone https://github.com/your_github_name/your_git_repo_name.git

Choose option 2 if you want to create a fresh new local repo (offline) which connects to your remote repo (online). This is an easier option if you want to start fresh!

In our case, you've already created a local repo on your AWS EC2 instance so you can choose option 1 to connect your remote repository (online) to your local repository (offline)!

  • Let’s switch back to the main branch:

git checkout main
  • origin is a local name used to refer to the remote repository. It could be called anything, but origin is a convention that is often used by default in git and GitHub, so it’s helpful to stick with this unless there’s a reason not to.

git remote add origin https://github.com/your_github_name/your_git_repo_name.git
  • We can check if our command has worked by list all remotes:

git remote -v
Screenshot illustrating git remote -v
  • Now we will push the changes from our local repository to the repository on GitHub:

git push -u origin main
  • Unfortunately, Github is no longer to support authenticate with username and password:

Screenshot illustrating Unfortunately, Github is no longer to support authenticate with username and password:
  • We need to generate personal access token of Github to authenticate ourselves to push all existing commits on the local repository to the remote repository on Github:

Screenshot illustrating commits on the local repository to the remote repository on Github:
Screenshot illustrating commits on the local repository to the remote repository on Github:
Screenshot illustrating commits on the local repository to the remote repository on Github:
Screenshot illustrating commits on the local repository to the remote repository on Github:
  • Select these permissions of the access code to be able to have full control of your private repositories, full controls of your team projects and also able to delete repositories:

    • repo = Full control of private repositories

    • admin:org = Full control of orgs and teams, read and write org projects

    • delete_repo = Delete repositories

Screenshot illustrating delete_repo = Delete repositories (1 of 2)Screenshot illustrating delete_repo = Delete repositories (2 of 2)
  • Remember to copy this personal access token somewhere safe!

Screenshot illustrating Remember to copy this personal access token somewhere safe!
  • Now you can use this personal access token to authenticate to push to your remote repository on Github:

Screenshot illustrating Github:

This Github authentication using an access token is easy to setup but it is a bit painful to re-enter the 🙁 access token every time you want to push to remote repository on Github !

  • Now, you should see all the commits we have done so far in the Challenge 0 has been pushed to the remote repository on Github:

Screenshot illustrating the remote repository on Github:
  • You can see that the list of our commits in the local repository has been pushed to the remote repository on Github:

Screenshot illustrating repository on Github:

Question: Did you notice your new_feature branch is missing on the Github remote repository? Can you figure out how to push the new_feature branch from the local repository also to the remote repository?

Hint : just switch to that brand and try to git push and see what happens then follow the instructions of Git.

Step 3: Synchronise local and remote repositories

After you follow the step 2, your local git should be connected with your remote git and you did your first push to the remote git repo.

git branch -a

Question : Do you notice anything different in your branches ? What is the "remotes/origin/main" branch?

Screenshot illustrating Question : Do you notice anything different in your branches ? What is the "remotes/origin/main" branch?
  • Let's switch back to the main branch

git checkout main
  • Let's pull any new update of content from the remote git

git pull

Because there is no new content on your remote git so the result is "Already up to date."

  • Check your git log

git log
  • Okie, it's time to add some file to the local git, add, commit and push it to the remote git

touch my_greeting.txt
echo Hello From Local Computer >> my_greeting.txt
git add .
git commit -m "add my_greeting.txt on my local"

These steps so far happen on the local git or on your laptop.

  • Let's push the new commit to the remote git

    • You might need to enter the Github access token again for authentication before you can push to the Github repository.

git push
Screenshot illustrating git push

That's it! Now your new changes are pushed to the remote git! That's how you can work on local git and remote git!

Remember to do git pull first before you do git push!

How to setup SSH key-pair for Github authentication

Note: There is a much better but more advanced way to authenticate for Github is to create a SSH key-pair (public and private key). The idea is that the EC2 instance got the private key and the Github got the public key and that’s how they authenticate each other! You can try to follow this setup here (Read the section 7.3).

Or you can follow these steps to setup Github authentication using SSH private and public key:

  • On your EC2 instance, generate a new SSH key pair:

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
  • When prompted, press Enter to save the key to the default location. You can skip the passphrase by just pressing Enter to have an empty passphrase.

Screenshot illustrating passphrase by just pressing Enter to have an empty passphrase.
  • Add Your SSH Key to the ssh-agent

    • Start the ssh-agent in the background:

eval "$(ssh-agent -s)"
Screenshot illustrating eval "$(ssh-agent -s)"
  • Add your SSH private key to the ssh-agent:

ssh-add ~/.ssh/id_rsa
Screenshot illustrating ssh-add ~/.ssh/id_rsa
  • Copy the SSH Public Key

    • You need to copy the content of your public key file. You can display and copy it using:

cat ~/.ssh/id_rsa.pub
Screenshot illustrating cat ~/.ssh/id_rsa.pub
  • Add the SSH Key to Your GitHub Account

    • Go to your GitHub account settings.

    • Navigate to the “SSH and GPG keys” section.

    • Click on “New SSH Key,” give it a descriptive title, and paste the copied public key.

    • Save the key.

Screenshot illustrating Save the key.
Screenshot illustrating Save the key.
Screenshot illustrating Save the key.
  • Test Your SSH Connection

    • Go back to your EC2 instance, to ensure that everything is set up correctly, try to connect to GitHub via SSH:

      • If successful, you should receive a welcome message from GitHub.

ssh -T git@github.com
Screenshot illustrating ssh -T git@github.com
  • However, there is one more thing we need to do! The local repository is set up to use HTTPS instead of SSH for the remote URL. We need to switch the remote URL from HTTPS to SSH!

  • Check Current Remote URL: First, check what the current remote URL is set to:

    • This will show you the URLs for your remote. If it starts with https://, then it's set to use HTTPS.

git remote -v
Screenshot illustrating git remote -v
  • Switch to SSH : To switch to SSH, you'll need the SSH URL of your GitHub repository. This typically looks like git@github.com:username/repository.git, which you can find here!

Screenshot illustrating looks like git@github.com:username/repository.git, which you can find here!
  • You can change the remote URL with the following command:

    • Replace username and repository.git with your actual GitHub username and repository name.

git remote set-url origin git@github.com:username/repository.git
  • Verify the Change: Run git remote -v again to make sure the remote URL has been updated to the SSH format.

git remote -v
Screenshot illustrating git remote -v
  • That’s it! Now you can do all remote git commands without a need to enter your username and password ever again like git clone or git push. You can make some changes, git add then git commit, finally git push to see if you can push without being asked for username and password of Github again!

Screenshot illustrating Github again!
  • By switching to an SSH URL for your remote, you leverage the SSH keys method you've already set up for authentication, thus avoiding the need to enter your username and password for operations like git push!!!

How to handle Merge Conflicts

Let's learn how to resolve merge conflicts.

  • Create a New Branch:

    • Create a branch named feature-login

git checkout -b feature-login
Screenshot illustrating git checkout -b feature-login
  • Confirm if you are already on the feature-login branch

git branch -a
Screenshot illustrating git branch -a
  • Add a New File:

    • In the feature-login branch, create a file named login.txt and some text related to login features:

echo "console.log('some login features')" > login.txt
  • Stage, Commit, and Push Changes:

    • Add the login.txt file to staging:

git add login.txt
  • Commit the changes:

git commit -m "Add login feature"
  • Push the branch to GitHub:

git push -u origin feature-login
Screenshot illustrating git push -u origin feature-login
  • Merge the Branch:

    • Switch back to the main branch:

git checkout main
  • On the main branch, let's merge the login-feature branch into main branch so that it got the login.txt file as well

git merge feature-login
Screenshot illustrating git merge feature-login
  • Push the merged changes to GitHub:

git push origin main
Screenshot illustrating git push origin main
  • Confirm the new change has been pushed to the main branch on Github:

Screenshot illustrating Confirm the new change has been pushed to the main branch on Github:
  • Create Conflicting Changes:

    • On the main branch, modify login.txt by adding "Here are some text Version 1" at the bottom. Alternative, you can use VSC for this:

nano login.txt
Screenshot illustrating nano login.txt
  • Commit and push these changes to GitHub.

git add .
git commit -m "add Version 1 to login.txt"
git push
  • Confirm the change on the main branch:

Screenshot illustrating Confirm the change on the main branch:
  • Switch to feature-login and also modify login.txt by adding "Here are some text to cause a conflict Version 2" at the bottom. Alternative, you can use VSC for this:

git checkout feature-login
nano login.txt
Screenshot illustrating git checkout feature-login nano login.txt
  • Try to push these changes.

git add .
git commit -m "add Version 2 to login.txt"
git push
  • Confirm the change on the feature-login branch:

Screenshot illustrating Confirm the change on the feature-login branch:
  • Resolve the Conflict:

    • When you encounter a merge conflict after trying to push, pull the changes from main:

      • git pull origin main

Screenshot illustrating git pull origin main
  • The issue arises because your feature-login branch and the main branch have diverged—they both have unique commits that the other doesn't have. When you try to pull changes from main into feature-login, Git doesn't know whether to merge or rebase the changes.

    • To resolve this conflict, you need to specify how Git should handle the divergent branches. Here are the steps:

    • Choose your reconciliation strategy :

      • Option 1 - Merge : Combines the histories of the two branches, creating a new merge commit.

      • Option 2 - Rebase : Reapplies your commits on top of the main branch, creating a linear history.

      • Both options have pros and cons:

Screenshot illustrating Both options have pros and cons:
  • Since our goal is to keep both sets of changes without altering commit history too much, I’d recommend the merge option (--no-rebase).

    • Execute the chosen command:

      • For Option - merge:

git pull origin main --no-rebase
Screenshot illustrating git pull origin main --no-rebase
  • You're encountering a merge conflict in login.txt during the merge. Let's resolve this step by step as below!

    • Verify the status of your repository, you should see that login.txt has conflicts:

git status
Screenshot illustrating git status
  • Open login.txt with nano to see the conflict markers:

nano login.txt
Screenshot illustrating nano login.txt
  • Decide how you want to merge the changes:

    • Option 1: Keep both versions.

      • Option 2: Choose one version over the other.

        • Option 3: Manually combine the changes.

      • Ensure all conflict markers (<<<<<<<, =======, >>>>>>>) are removed after resolving.

      • For example, in my case, I will clean up the conflict markers and create a new text to show I have resolved the conflict:

        • For example, in my case, I will clean up the conflict markers and create a new text to show I have resolved the conflict:

Screenshot illustrating new text to show I have resolved the conflict:
  • Mark the conflict as resolved by adding the file:

git add login.txt
git commit -m "Resolve conflict between main and feature-login"
Screenshot illustrating git add login.txt git commit -m "Resolve conflict between main and feature-login"
  • Finally, let’s push the merge commit to our Github repo:

git push
  • Optionally, you can check the log to verify the commits:

git log --oneline --graph --all
Screenshot illustrating git log --oneline --graph --all
  • Check the result on Github:

Screenshot illustrating Check the result on Github:
Screenshot illustrating Check the result on Github:

These exercises cover basic Git commands and scenarios involving creating and managing branches, handling merge conflicts, and collaborating using GitHub. They are a great way for you to get hands-on practice with Git.

Screenshot illustrating practice with Git.

🧪 Challenge 2: Work with your assigned private repository

Screenshot illustrating Challenge 2: Practice with Your Private GitHub Repository in Our GitHub Organization

As announced on Canvas, each student has been assigned a private GitHub repository in the rmit-vietnam-computing-technologies GitHub organization. This repository is provided for testing and practice. You should use it to practise the Git commands and GitHub authentication process before the in-class exam.

During the exam, you will receive a different private repository with a similar setup. Therefore, make sure that you understand the complete process rather than simply copying the commands.

Step 1: Accept the GitHub repository invitation

GitHub will send an invitation to the email address linked to your GitHub account.

  • Open the invitation email and accept the invitation within seven days.

  • The invitation will expire after seven days if it is not accepted.

  • Check your spam, junk, or promotional folder if you cannot find the email.

  • Make sure that you are signed in to the correct GitHub account before accepting the invitation.

  • After accepting the invitation, visit:

  • Check that you can see and access your assigned private repository.

  • Your repository name should follow this format:

<year>-<course>-<assignment>-<campus>-<your-github-username>-<your-student-id>
  • For example:

2026b-cosc2767-testing-sg-theodore-huynh-s123456

Use only the private repository assigned to you. Do not create another repository in the organization, rename the assigned repository.

Screenshot illustrating rename the assigned repository.

Step 2: Configure GitHub authentication with SSH

Because this is a private repository, GitHub must authenticate you before allowing you to fetch, pull, or push repository content.

For this challenge, use SSH key-pair authentication. With SSH authentication, your computer or EC2 instance stores the private key, while your GitHub account stores the matching public key.

If you have done the SSH Key Pair setup in Challenge 1, then you can skip this step. If not, then follow the steps in challenge 1 to set up the SSH Key Pair in your EC2.

Step 3: Create the local repository

Repeat the main activities from Challenge 0 by creating a local repository with some local commits.

At this point, your local git repo was initialized and therefore have different commits in the git log history.

Below screenshot is exactly our local git repo commit history at the end of challenge 0 (before challenge 1)!

Screenshot illustrating 1)!

Step 4: Connect to the assigned private repository

Open your assigned repository on GitHub and copy its SSH URL. The URL should look similar to:

git@github.com:rmit-vietnam-computing-technologies/2026b-cosc2767-testing-sg-yourusername-s123456.git
Screenshot illustrating git@github.com:rmit-vietnam-computing-technologies/2026b-cosc2767-testing-sg-yourusername-s123456.git

Add the assigned repository as the origin remote:

git remote add origin
git@github.com:rmit-vietnam-computing-technologies/<your-assigned-repository-name>.git

Check the remote configuration:

git remote -v
Screenshot illustrating git remote -v

Both the fetch and push URLs should use the SSH format beginning with (“ git@github.com: ”):

origin git@github.com:rmit-vietnam-computing-technologies/2026b-cosc2767-testing-sg-theodore-huynh-s123456.git ( fetch )
origin git@github.com:rmit-vietnam-computing-technologies/2026b-cosc2767-testing-sg-theodore-huynh-s123456.git ( push )

[Only follow these steps below if you receive the following error “error: remote origin already exists”. Otherwise, skip to step 5] when running the command “ git remote -v ” or “git remote add origin” :

  • This means that your local git repo has assigned a origin remote Github repo before so you cannot just add a new origin remote as you need to update it instead!

Screenshot illustrating cannot just add a new origin remote as you need to update it instead!
  • Update the existing remote instead (to replace the previous origin remote):

git remote set-url origin
git@github.com:rmit-vietnam-computing-technologies/<your-assigned-repository-name>.g
it
Screenshot illustrating git remote set-url origin git@github.com:rmit-vietnam-computing-technologies/<your-assigned-repository-name>.g it
  • Then check it again:

git remote -v
Screenshot illustrating git remote -v

Step 5: Fetch the existing remote content

Unlike the empty public repository used in Challenge 1, your assigned private repository already contains files such as README.md and .gitignore.

Do not immediately push your local commits as the remote Github repo has an existing commit with some files (README and .gitignore) so you will not be able to push without pulling and merging first.

So if you try to push it, you will see this error:

Screenshot illustrating So if you try to push it, you will see this error:

First, download information about the existing remote branches and commits:

git fetch origin

The git fetch command downloads the remote branch information and commits but does not modify the files in your current working directory.

Screenshot illustrating files in your current working directory.

List all local and remote branches:

git branch -a

You should see your local main branch and a remote-tracking branch similar to “ remotes/origin/main ”:

Screenshot illustrating You should see your local main branch and a remote-tracking branch similar to “ remotes/origin/main ”:

Inspect both the local and remote commit histories:

git log --oneline --graph --decorate --all

You may notice that the local main branch and origin/main have separate starting commits. This happens because the local repository and the GitHub repository were initialized independently.

Screenshot illustrating because the local repository and the GitHub repository were initialized independently.

Step 6: Set the upstream branch

Connect your local main branch to the remote origin/main branch:

git branch --set-upstream-to=origin/main main
Screenshot illustrating git branch --set-upstream-to=origin/main main

Check the branch relationship:

git branch -vv

The output should show that your local main branch is tracking origin/main .

Screenshot illustrating The output should show that your local main branch is tracking origin/main .

An upstream branch tells Git which remote branch should normally be used when you run commands such as “ git pull or “git push ” without writing the remote and branch names every time.

Step 7: Combine the local and remote histories

Before pushing, pull the existing files and commits from the assigned repository:

git pull --no-rebase --allow-unrelated-histories --no-edit

The options have the following purposes:

  • --no-rebase tells Git to combine the histories using a merge rather than rewriting your local commits.

  • --allow-unrelated-histories allows Git to merge repositories that were initialized separately.

  • --no-edit accepts Git’s default merge commit message.

The --allow-unrelated-histories option should normally only be required for the first merge between these two independently created repositories.

Screenshot illustrating two independently created repositories.

If the local and remote repositories contain different filenames, Git may merge them automatically. After the pull, check the result:

git status
git log --oneline --graph --decorate --all
ls -la

You should now have both:

  • The files that you created locally.

  • The existing files from the private GitHub repository, such as README.md and .gitignore.

Screenshot illustrating The existing files from the private GitHub repository, such as README.md and .gitignore.

[Only follow these steps if you have a conflict to resolve a merge conflict if one occurs] ( maybe happens because you got existing .gitignore or README on your local main already before the merge happens so it conflicts because it cannot merge either .gitignore or README between local main and origin/main) . [Otherwise, please skip to step 8!]

A conflict may occur if both repositories contain different versions of the same file.

Check the conflicting files:

git status

Open each conflicting file and look for conflict markers similar to:

<<<<<<< HEAD
Your local content
=======
Content from the remote repository
>>>>>>> origin/main

Edit the file so that it contains the correct final content, and remove all conflict markers.

Stage the resolved file:

  • For example: git add README.md

git add <filename>

Complete the merge:

git commit -m "Merge assigned repository with local practice history"

Check that there are no unresolved conflicts:

git status

Step 8: Push the existing local commits

After successfully fetching and merging the remote content, push the combined history to your assigned private repository:

git push
Screenshot illustrating git push

Because the upstream branch has already been configured , Git knows that the local main branch should be pushed to origin/main .

Optional that if you want to, you can also explicitly write the remote and branch instead of just “git push”:

git push origin main

Return to your repository on the GitHub website and refresh the page. Confirm that you can see:

  • Your local practice file.

  • The original README.md and .gitignore files.

  • Your local commits.

  • The merge commit that combined the local and remote histories.

Screenshot illustrating The merge commit that combined the local and remote histories.

Your tasks (if you want more practice):

  • Practise the Normal Pull–Commit–Push Workflow:

    • Make another local change.

    • Stage and commit the change.

    • Before pushing, pull and merge any new remote updates.

    • Then push your commit.

    • For example, the normal workflow is:

git status
git pull --no-rebase
git add .
git commit -m "Describe the change"
git push
  • Make sure that your current work is committed or safely stored before pulling remote changes.

  • Practise with a New Branch:

    • Create a new local branch.

    • Create and commit a file.

    • Push the new branch and configure its upstream branch. (for example, “ git push -u origin practice-feature )

    • List the local and remote branches.

    • Switch back to main.

    • Pull the latest remote changes (for example “ git pull --no-rebase ”)

    • Merge the practice branch.

    • Push the updated main branch.

    • Check the repository and branch list on GitHub to confirm that both branches were pushed successfully.

🧪 Challenge 3: Collaborate with a partner using Git

Screenshot illustrating Challenge 3: Remote Git + Collaboration with your friends (in pair)

Try to pick one person in your team to create a remote repo, add the other person to the remote git and two people try to push code to the remote git!

The knowledge of Git will be super valuable to the Continuous Integration pipeline!

  • Ask for the username of the person you're inviting as a collaborator. If they don't have a username yet, they can sign up for GitHub For more information, google "Signing up for a new GitHub account".

  • On GitHub, navigate to the main page of the repository.

  • Under your repository name, click Settings.

  • Click Invite a collaborator.

Screenshot illustrating Click Invite a collaborator.
  • In the search field, start typing the name of the person you want to invite, then click a name in the list of matches.

  • Click Add NAME to REPOSITORY.

  • The user will receive an email inviting them to the repository. Once they accept your invitation, they will have collaborator access to your repository.

Now that invited user should receive an email of collaboration and they should accept it to start collaborating!

Now those people who are collaborators will be able to git clone!

Your task :

  • Each person should try to push their own files to the remote repo and please add a file like your_name.txt and inside say "Hello! My name is ...!".

  • Try to create a conflict by both editing the same file on the same file on different branches then try to merge both branches back to the main brain.

  • Then try to resolve the conflict.

  • Next, one person try to create a pull request and the other person try to accept that pull request.

Have fun!

A pro tip for you guys in the actual group project:

You could establish these rules when naming a branch on Github:

  1. features/{feature-name} - This convention is used when developing new features

  2. fix/{bug-name} This convention is used when fixing bugs in the development environment.

  3. hotfix/{bug-name} - This convention is used when fixing bugs in the production environment

Here are the example branch names: features/home-page, features/user-post, features/admin-pages, features/sitemap, fix/user-database, fix/responsive-my-account, fix/change-color-focus-visible, fix/light-dark-mode-when-logout, hotfix/init-database-config-path

You can use the Best Practices as following:

  1. Branching Strategy: You can use a clear branching strategy with features/ branches for new features developed in the development environment, fix/ branches for bug fixing, and hotfix/ branches for urgent production issues.

  2. Regular and meaning commits: Team members commit the changes of code to their features or fix bug branches to ensure seamless integration with detailed and informative commit messages to provide clear purposes.

  3. Code Reviews:

    • All pull requests must be reviewed and approved by at least one other team member before merging.

    • Reviewers will check for code quality and ensure there are no code conflicts before merging.

  4. Merge Strategy:

    • Features/ branches will be merged into the main branch after code reviews are approved.

    • Fix/ branches will be merged into the main branch after code reviews are approved.

    • Hotfix/ branches will be merged into the deploy branch if there are any emerging issues in the production environment and resolved in hotfix/ branches.

🎮 Bonus: Practise Git with Oh My Git!

Screenshot illustrating Bonus Challenge Game: Oh My Git! game about learning Git!

Oh My Git! is an open source Git learning game! See ohmygit.org and the GitHub project for details!

Oh My Git! visualises the internal structures of Git repositories in real time. To accommodate people who are new to Git, the game features a custom-designed playing card interface! The cards help remember newly introduced Git commands, but also contain a short description and an icon. Therefore, they combine both action as well as documentation:

Here are some screenshots and demo videos:

Screenshot illustrating Here are some screenshots and demo videos:
Screenshot illustrating Here are some screenshots and demo videos:
Screenshot illustrating Here are some screenshots and demo videos:

You can download the installation files to install on your personal laptop for Linux, macOS, and Windows here: https://blinry.itch.io/oh-my-git

Screenshot illustrating here: https://blinry.itch.io/oh-my-git

🌿 Git command reference

  • git clone <url> : makes a copy of a repository and stores it on your computer.

  • git init : makes the current folder as a git repository

  • git add : adds a file to "staging area", which means telling git to include the file in the next time it saves a version of the repo. git add . to add all changed files.

  • git status : a helpful command, to see what's currently going on in the git repo

  • git commit: saves the version of the repository.

  • git push -u origin main: pushes the changes I made on my computer up to the Github repo

  • git pull : is opposite of git push, pull the most recent version of the online repository.

  • Merge Conflicts: Let say two developers work on the same line of a file, and both of them push the code up to Github. So Git's not going to be able to know what to do in that situation, because it doesn't know which kind of version of the code to believe. So you have to resolve that merge conflict by specifically telling Git which version of the code you want to use.

  • git log: to see all the version that you have saved and you can see the commit message is a very good indicator or reminder of what was changed in a particular version. So make sure you use good commit messages.

  • git reset --hard <commit> : reverts code back to a previous commit

  • git reset --hard origin/main : reverts code back to remote repository version

  • Branching: Branch is a version of the repository. Each branch has its own commit history and current version.

  • git branch : shows all branches of code

  • git branch <branch_name> : creates a new branch

  • git checkout <branch_name> : switches to a branch

  • git merge <branch_name> : merges the branch with current branch

  • git config --global alias.sla 'log --oneline --decorate --graph --all makes git log a bit prettier.

Screenshot illustrating prettier.

📚 Continue the course