This post series is indexed at NgateSystems.com. You'll find a super-useful keyword search facility there too.
Last reviewed: Dec '24
1. Introduction
As an IT beginner creating your first VSCode project, learning Javascript, and exploring the wonders of Svelte, probably the last thing on your mind will be the thought of turning your project into a Git repository (whatever that might be!). But with experience, you'll start to realise that managing the source code in your project is quite a challenge. You will make changes, find that you've got into a mess and want everything to return to a stable state so you can try again. Hmm. How do you manage to do that?
Post 1.1 mentioned VSCode's "timeline" facility. This lets you view a time-stamped list of "saves" on a file and enables you to select any of these to replace the current version. This is fine in its own way but has obvious limitations - for example, what if you wanted to reset a whole bunch of files to a particular point? Git, by contrast, is "timeline" on steroids (and then some!)
Git's "repository" mechanism wraps a project's files up in a framework that tracks changes between "commit" points. A "commit" enables you to sign off a whole collection of file changes as a "recovery" point for your project. Then, if things go badly wrong, you can use Git to roll back the entire project to whatever commit point you choose. Even better, you will still have access to your abandoned changes.
Git also provides a "push" concept that enables you to maintain a copy of your local project on the web. With this in place, your carefully crafted project won't vanish into history when you leave your laptop on the bus! Typically, you would use this to create a secure backup "recovery" copy of your code when you deploy a new version of your webapp. In many workflow designs, in fact, a Git push is the procedure you use to automatically trigger a deployment.
But in describing the "remote repository" concept in this way, I'm seriously understating its significance. In the world of serious systems engineering, the remote repository is the point through which large teams of developers, each operating on a local copy of the project code, coordinate their work. Git software provides the means of imposing order on what would otherwise be a nightmarish struggle.
When a team member wants to merge their changes into the master repository, they make a "pull request" rather than a "push" instruction. This invites the repository controller to review the proposed changes and negotiate with the developer over any necessary adjustments. When such a pull request is finally accepted, the associated changes are merged with the master repository. Other developers must now update their local repositories so they in turn receive "pull requests" from the owner, asking them to synchronise their local code with the master repository. However, this may require them to apply consequential changes to the code that they are currently developing - and so the cycle continues.
A description of these "team" arrangements is well outside the scope of this post - the Pro Git book would be an excellent place to take you to a higher level. For now, here are detailed instructions for the things you are most likely to want to do as a beginner:
- Turn the code for an existing local project into a repository and create a commit point
- Recover to a commit point
- Create a master repo on the web and synchronise this with a local repo.
- Clone a public repo from the web to obtain a local copy of its code.
2. Turn the code for an existing local project into a repository and create a commit point
This is quite a complex procedure, but if you take it step by step and use chatGPT to resolve any problems, you should be fine. Here we go:
First of all, you'll need to install Git software on your local machine). You'll find instructions for this at Git Downloads. The procedure adds library code to your machine that lets you use both "raw" Git commands in terminal sessions and "packaged" Git tools in VSCode. Initially, in this post, I'll be typing "raw" commands into a terminal session. Horrible as these are, I think they give you a better feel for what's going on than the packaged tool.
Now open a terminal session for your project and type the command
git init
. This reports back that an empty git repository has been established in your project. If you look at your project in Windows Explorer, you'll find that you can actually "see" the repository - it takes the form of a.git
folder in the project root. If you ever get in a total mess with Git and feel you need to start again, all you need to do is delete this file!At this point, although you've got a repository, Git isn't actually doing anything useful. None of your files is currently "tracked" by the version control system - Git doesn't know which files you want it to manage yet, and a "commit" request will simply leave the repository in its current, empty state. Since you probably want it to track all your files, now type
Git add .
into your terminal session. The.
her means "please track all my files". Ignore any warnings about line-ending inconsistencies here - the Unix world that created files likejsconfig.json
at project-initiation time used "LF" characters to terminate lines, while the Windows environment in which they'll now be edited uses "CR/LF". You can confidently leave VSCode and Git to sort this out between them.Now create a
commit
point for your local repository with agit commit -am "Your commit message"
terminal command. The "Your commit message" bit here is a unique tag used to identify commit points later Writing "commit messages" is an art form. You're forced by the system to keep the first line of the message short - 50 characters max. A typical commit statement would look likegit commit -am "Stable login added"
. Ask chatGPT if you'd like to get advice on how you might add supplementary information.
3. Recover to a commit point
This is where things start to get interesting. Try a little experiment. Make a few random changes to several files in your project and save them. Then, imagine you've changed your mind and want to revert your project to its initial state.
Type
git restore .
into your terminal session. Now, check your project. Yes, all the changes made since your last commit have been washed away. Wonderful!The simple "restore" command introduced above restores your project to the most recent commit. How would you proceed if you wanted to restore an earlier commit? First, type the following into your terminal session:
git log --pretty=format:"%h : %s"
. This is a "prettified" - i.e. summarised and formatted - version of a basic (but rather verbose)git log
command. It will produce output like:c9f6037 : Stable login added
. Thec9f6037
bit here is the "short hash" abbreviation for the full 40-character identifier for the commit. You can restore your project to the "Stable login added" commit point in the example above with the following command:git restore --source "short-hash" -- .
(where "short-hash" is the short-hash for your particular commit).Now that you've got a basic feel for how Git works, you'll find it useful to try the option of using VSCode facilities to make commits. If you click the "Source Control" in the toolbar column at the LHS of the VSCode screen, a list of the changed files in your project will be displayed. Clicking on any of these will show you exactly what changes have been made since the last commit. To create a new commit point, simply enter a commit message for your project (taking care to select the correct section if you have multiple projects in your workspace) and click the blue "Commit" button.
A VSCode popup may now confuse you. It asks, "Would you like to stage all your changes and commit them directly?". This is your first encounter with another layer of version-control practice. Here's the background. A common experience is that a requirement for an urgent bug fix will emerge just as you're halfway through developing a new feature. In this situation, you'll want to commit to the fix whilst reserving judgment on the incomplete new feature. "Staging" enables you to commit only selected files. Assuming the two developments are in separate files, you can then select the files you want to be "staged" (ie included) in the commit by mousing over entries in the "changed files" list and clicking the "+" ("stage changes") symbol thus revealed. Take care not to click the "discard changes" option also available here unless you really know what you're doing - this could, irreversibly, lose you a lot of useful work! Yet more complex facilities are available to enable you to stage only selected sections of a file, but these won't be described here. Ask chatGPT for details if you feel the need.
In present circumstances, you'll most likely want to commit all your changes, so select the "stage all changes" option when committing.
4. Create a master repo on the web and synchronise this with your local repo.
As described earlier, creating a master repo on the web will provide a secure backup for your local work. This will involve some small investment of your time, but this might repaid many-fold in future.
To get started, you'll first need to create a GitHub account. GitHub is a developer platform owned and operated by Microsoft. You can create a (free) account at Github Home Page. I'm not going to describe this procedure here because it's a bit complicated and may be subject to change. Ask chatGPT for advice if you get into trouble.
Now, use your new account to log into GitHub. Click your profile icon, select "Your Repositories" (an empty list at present) and click the "New" button. Give your repository a name - you'll probably want to choose something based on your VSCode project name - and tell GitHub whether it is to be public or private. If you select public, others can view it on the web and "clone" (ie download) it as a local repository on their own devices (as you'll see later). You'll probably want to select "private" at this stage - you can always change your mind later. Decline creating .
gitignore
orreadme
files too. You'll complicate things enormously if you add anything to your new repo at this point. You can safely ignore the offer to create a license, so now just click the green "Create repository" button at the bottom of the page.Now, you need to link your local repository to the remote repository you've just created and push your local content into it. You do this with a series of commands that you enter into a terminal session on your project. To save your typing, Github will provide the following default script.
git remote add origin "your repo address"
, thengit branch -M main
, and finallygit push -u origin main
Copy and paste the GitHub script into your local terminal session.
The "add origin" bit will declare your GitHub repository as the remote repository for your local repo. The "branch -M" bit will rename your local repo as "main". Finally, the "push" command will copy the content of your local repo to the GitHub version. Confirm that this is actually the case by clicking on your repo name on the Github "My Repositories" page and exploring its file hierarchy. You should find that they're a mirror image of your local repo.With your remote repo in place as a "master" statement of your project source, you should experiment with the procedure for maintaining this situation as you continue to make and commit local changes. Repeat your previous exercise - make a few changes to some testbed project files, and use VSCode to commit them as described earlier. When you've provided a commit message, clicked the Commit button and selected the "stage all changes" option, you should see a new button labelled "Sync Changes?". Clicking this will automatically update your remote repo, thus maintaining its integrity as a copy of your local repo.
A common error when making a commit is to forget to provide a "commit message". When this happens, Git will open a "COMMIT_EDITMSG" file in the editor and wait for you to overwrite its content with whatever you should have entered in the normal Message box. Once you've saved and closed this file, the commit should proceed normally
5. Clone a public repo
GitHub has become a hugely valuable software "exchange" enabling developers to collaborate on code projects. Here's how to obtain a copy of a public GitHub repo.
Launch a terminal session in VSCode and navigate to the "root" of the folder where you keep your development projects. Typically, you might do this by opening the session on an existing project and then entering a
cd ..
command to lift the session one level higher in the folder hierarchy.Now execute the following command:
git clone <repository-url>
, where<repository-url>
is the URL of your target open-source GitHub repository. This will add the repository to your local filing system, leaving you only to "add a folder to your workspace" to view it in VSCode.With a copy of an open-source project on your own machine, you're now free to use this as you wish. It may be that you are interested in adding features and making your own contributions to the project. In this case you'll want to submit "pull requests" to the owners of the project requesting them to review your work and to consider incorporating it into the project. Arrangements here vary widely, so follow their instructions and ask chatGPT for advice as necessary.
6. Postscript
While this post has provided the basics for using Git on personal projects, it has only scratched the surface of what Git can do for you when working collaboratively on large-scale developments. For this you really do need to spend some time with the "Pro Git" book mentioned earlier. In the meantime, here are explanations of a few additional Git terms that you may encounter:
-
Fork - In contrast to the procedure for creating a copy of a GitHub repository on your local computer with a "clone" command, a "fork" request creates a web-based copy in your GitHub account. If you're working on an open-source project, the administrators will probably find it much easier to work on your pull requests when they come from a repo on GitHub rather than from your local computer. You "fork" a repo using the Fork button on the source repository's GitHub page. Your workflow on an open-source collaboration would thus likely be "fork", "clone", "develop locally", "push (to a GitHub repo of your own creation)", and finally, "make pull requests from the new GitHub repo". Ask chatGPT for advice on how to make such requests, if necessary.
-
Branch - A branch in Git is essentially a pointer to a particular commit in the repository's history. It allows you to work on a separate version of your project without affecting the main codebase. Effectively, you might say, it creates a parallel line of development. You create a branch by using a
git branch <branch-name>
command, where<branch-name>
might be something likefeature-x
. To start working on this branch, you would use agit switch feature-x
command. If things go well and you want to incorporate the changes into your main branch, you would first switch back to the main branch with agit switch main
command and then incorporate the feature branch changes into this using agit merge feature-x
command. Alternatively, if you decided the changes weren’t working out and wanted to revert to your original branch, you should simply stage and commit your changes on the feature-x branch (so that Git doesn't, by default, "persist" uncommitted changes in the working directory) and then switch out of thefeature-x
branch with agit switch main
command. Previously, you might have usedgit restore
to discard uncommitted changes on the main branch. Making your changes on a new branch enables you to recover them should you change your mind. HEAD is a "pointer" to the latest commit on the branch you're currently working on. Many Git commands use HEAD as a default reference. For example:
Command | Action |
---|---|
git show HEAD | View the details of the latest commit |
git diff HEAD~1 | Compare the current commit with the previous one |
git reset --soft HEAD~1 | Undo the latest commit but keep changes staged |
Top comments (0)