These notes support a demonstration and talk that introduces PowerShell users to Git and version control concepts. An hour talk is not very long and these notes are brief, so links to more complete material are provided.
Note: This content is written in British English
Most folks in IT (application developers, system administrators, security engineers,…) create, and manage, text files of various types all day, every day. For example: scripts; data files of various types (such as config settings stored in JSON or CSV files); application source code and so on. Keeping track of changes, looking back at old versions and creating special purpose versions is unmanageable without a version control tool.
Git is the world’s most popular version control tool. This talk provides a novice introduction to using Git from the PowerShell prompt and no previous version control experience is assumed. As well as using Git locally, we will also look at storing version repositories on the GitHub cloud service.
Because this is an introduction additional resources will be provided to take people further on their Git journey.
Things we’ll talk about
In the following explanations we will talk about developers and that means you, because you write PowerShell scripts…
If you write code you’re a dev
Alec is an IT geek who currently works as a Developer Advocate at PaperCut Software in Melbourne, Australia. He’s been using computers since the late ’70s (an ICL 2904 mainframe) and he was a MS-DOS batch file (and later UNIX shell) wizard. More recently Alec has been learning PowerShell, he always has Windows Terminal open with both a PowerShell and WSL2 Bash prompt available. Recently he installed VS Code on his ARM64 Chrome OS tablet
It’s hard, or even impossible, to keep track of all our important project files, why they were changed, or create new versions for specific purposes. When we work in a team on different changes to a common set of files, the complexity quickly becomes unmanageable.
Can also use PowerShell Module install, e.g.
Install-Script Install-Git ; Install-Git.ps1 ; Install-Module posh-git ; Import-Module posh-git. However the Git Module does not present the standard CLI experience.
git config --global user.name "Alec Clews"
git config --global init.defaultBranch main(Needs Git 2.28 or above, more info here)
git config --global core.editor "code --wait"(VS Code example)
git config --global core.autocrlf inputso that you play nice with UNIX style line endings, see also Git for Windows: Line Endings for another solution using
Note: Most guides now suggest you configure
user.email at the same, however if you commit under different identities, for example your company email address and personal email for FLOSS side projects, you need to take some precautions.
Option 1: Each time you create a new repo create a repo specific config entry with the correct email address. For example (after running
git init) run
git config user.email firstname.lastname@example.org. (Note: No
--global option so it’s local to the current repo.) This is approach used in the demonstration. You can even wrap the Git
init command if you want.
Option 2: If you use a consistent directory structure then you can use Conditional Includes to configure your email address automagically.
Your config settings are stored in
Git runs on Windows, MacOS, and Linux
Git provides commands to add new changes, recover old versions and retrieve historical data
Each Git repo can connect and share code with other repos managing the same project. The action of creating a local repo based on an existing project is referred to as cloning
Because Git is distributed each repository clone has a (mostly) complete record of all changes
But as repos are cloned amongst multiple users each repo may have their own unique history.
Git maintains information about the other repos that it shares changes with in remote tracking branches
Git can handle large numbers of files (for example the GNU/Linux kernel source code). However if you have very large binary files then Git (or other general purpose VCS tools) may not be your best choice, but see Git Large File Storage.
Technically Git repositories have a peer to peer relationship.
In practice developers usually commit to a single upstream repository and
multiple workflows can be build on top of this model.
All changes can be shared with other repos as needed, usually to an “upstream” repo (by convention called
.gitdirectory, don’t worry about it for now
See also What is Git?
The Git command line interface consists of the executable
git followed by a command and the corresponding arguments and options.
There are many commands and a myriad of options so it can seem a little overwhelming all at once, we will focus on the basic workflow commands.
Note that the Git CLI follows UNIX/Linux conventions, not PowerShell.
There are many links to help you discover the details.
init allows you to initialise a new git repo inside a project that is not already under version control e.g.
git init <project_dir>
clone clones the complete history of a remote project. You can now work on a running project. For example, let’s clone the Git repo for these examples onto our workstation
git clone https://github.com/alecthegeek/git-from-powershell.git
Adding changes to a Git repo is a two stage process. All changes are staged in the index, before they’re committed into the repo.
Note: ALL changes, not just new files, need to be added to staged into the Index before they can be committed
git add <file-name> or
git add <directory-name> to add the changes in a directory tree.
After a changes has been assembled (staged) in the index (using
git mv, or
git rm) the change must be
committed into the repo with the
Before committing your changes
merge) any recent changes from your remote repositories (more on
During the commit operation provide a useful commit message
a well-crafted Git commit message is the best way to communicate context about a change to fellow developers (and indeed to [our] future selves). A diff will tell you what changed, but only the commit message can properly tell you why – Chris Beams
git checkout command allows you to move the current
HEAD to another point in the repo history or create a new branch
HEAD is the pointer to the current state of the working copy in source control, but without any changes you may have made in your working copy. Git will often tell you about
To move you working copy to another point in history use
git checkout <history reference> where the
history reference is the name of an exiting branch,
a tag, or some other reference to a previous commit the repo history.
To create a new branch use
git checkout -b new-branch-name
pull command downloads and merges changes from another remote repository, usually the upstream “origin” repository hosted on GitHub, or a similar service.
fetch which downloads the changes, but does not merge the remote changes.
Take the contents of two branches (the content must exist in your local repo) and combines them into single branch. Git will do it’s best, but will need help to resolve conflicts if changes on lines overlap. More details here.
GitHub upstream repos can be managed from the PowerShell prompt
Install the GitHub CLI (
gh) tool via Chocolaty
choco install gh
Now you can add your current project to GitHub
gh repo create --public
Push project code to GitHub
git push --set-upstream origin main
Now open the repository URL On GitHub.
The Git Parable. An introduction to the concepts behind Git
A nice, rapid, intro to VCS, Git and GitHub for web projects — applies to any type of project