Whether you write scripts in isolation or work with a team, the ability to track version of you scripts is important. You may add code that ends up not working out, and the ability to reverse these changes (without manually deleting code) can save your script. Git is a most common source control tool and keeps tracks of changes through commits. Creating a commit is like saving a file, except it keeps tracks of the file versions by associating a unique ID (or SHA or hash) with the commit. This unique ID allows for reverting to previously committed versions of files in the repository.
In a typical workflow, you would pull down the script from a remote repo, make changes to the file(s) locally on your system, commit the changes locally, then push the new file up to the repo. However, if you don’t have a central remote repository of your scripts or pushing/pulling/merging code makes you nervous, you can still take advantage of the commit process locally to track versions of your script, as well as reverting changes. I’m going to walk through some basic git commands and show how to revert to a previous of a script locally without the use of a remote repo.
The first Git command to start with git init. This command initializes a Git repository and adds a hidden folder named .git which keeps track of the current active branch, config files, aliases, etc.
Next, I need a script to work on and track changes. I created a simple script named myScript.ps1 which cycles through a for loop for a few iterations and outputs to the screen. I’m calling this first loop my outer loop.
The next step is to view that status of our repo by running git status. The status will show which branch you are on (topic for another time, just know you are on the “master” branch). It will also show any new or changes files since the last commit by displaying them in red.
If we want to track these files and make them available to commit any changes, we need to add them to our staging area using the git add command. The git add command can specify one or multiple files to add to the staging area. In our case, we only have one file, so we add it and check our status again to see our script is now green and being tracked in our staging area.
Now that we are tracking our file and added it to the staging area, we are ready to make our initial commit of our script using git commit. We use the -m parameter with a commit message in quotes. The commit message should be short but descriptive to indicate what changes have been made. Afterwards, we run another git status to see that no other changes are available and we are at the HEAD of our tree.
Next let’s go make some changes to our script, just going to add an inner loop.
If we run git status again, we’ll see the same results as we did earlier, it will show the file as being untracked as it has changed since our last commit. Run through our workflow of commands to add the file and commit it with a comment that we added an inner loop.
Now that we have a few commits in the repo, we can turn to the git log command. This will show our previous commits along with commit messages as well as the unique hash for each commit. The last commit we made for adding the inner loop is our current HEAD.
Now let’s say we don’t want our last changes and want to revert to an earlier version of the script. We could manually delete the inner loop, this script is small enough to do that, but larger scripts could pose a problem. You might end up removing too much or not enough code and waste time trying to fix it. Using the first 7 characters of the commit log hash, we can revert to a previous version of the script using the git reset command.
This resets HEAD to a specific commit. The screenshot is showing that myScript.ps1 is back to the staging area with the changes since the “a6dd1c2” commit. Running git log again will only show one commit in log as opposed to the two we had previously with HEAD now at the previous commit.
In order to switch completely back to our file, we need to checkout that version from the commit itself using git checkout. Once the file is checked out, I opened it in ISE to show that we are back to just having our outer loop, and running git status will show that our current tree does not have any changes to track.
Here is a quick break down of each command I used:
So if you’re new to version control but don’t have the confidence to work with remote repositories just yet, you can still work through these basic git commands to familiarize yourself with the process of how to use it for version control.