This is a view of my “GIT” Timeline from my Data Formatting / Parsing practice
This graphic alone did a lot to clarify GIT to me, as I initially had no idea what the Master Branch / What the head was / Where this “Version History” was at / How to use “Version Control” or “Change Control” using GIT – So in this page I will run through all of that.
Quick note – Found a great GIT cheat sheet my first day of DevNet Class below!
Also someone posted a great “GIT Cheat Sheet” PDF in todays DevNet class that I wanted to share right up front, as it is a great quick reference sheet when working with GIT:
Some of this is covered below, some of this will be covered in a more “Collaboration with GIT” post were this is more the foundational GIT information that is difficult to push through understanding but critical for working with it competently if you land a DevOps job as there are a lot of ways to create Repository Conflicts with the below information!
**** If you don’t read it here, do yourself a favor and study it somewhere, someday you will thank yourself you did when you DON’T break a production Repository with simple mistake that any DevOps Engineer should know! ******
So because the topics may not be on the Blueprint, they could be on the exam, and will definitely be part of your job some day as skilled DevOps Engineer 🙂
First I review the GIT Master Branch / Time Line / GIT Head placement via GIT CMD
This concept didn’t click for me until I started working within the GIT CMD Shell, like I’ve said there are lots of GUI’s out there to avoid using that just integrate your local PC with GITHUB, and use this GIT CMD Shell at the following URL:
You can also use the Native Bash prompt if your OS has one, though I use this GIT Shell to ensure I have all features for GIT, as I am on Windows OS (unless I need to work within my Ubuntu VM) – In Linux I would just work out of the Bash Terminal / MAC I don’t use and have no idea / Windows OS I would definitely use this tool!
(In the demo I am actually using the GIT CMD Terminal, though the download does include a Bash Terminal as well for Windows).
That being said, I will jump into it here, as there is quite a bit to cover!
Review of both Verbose (lots of output) and brief views of GIT Timeline / logs
First I will review the less verbose / brief view of GIT Timeline / logging:
Note that there is a 7-Digit Alph-Numeric value follow by the Commit Comment, each one of these Commits are a snapshot of the ENTIRE GIT REPOSITORY at that point in time, which is why good comments both naming the file and update briefly is important!
That bears repeating as I did not know this until I got into this section of GIT material, which is my Commit comments are pretty terrible, but when a Commit is done to a GIT Repository it takes a snapshot of that entire point in time!
Meaning if / when we revert back to a previous Commit later in this post, other files will be missing entirely that were Committed to the Repository after that point in time!
A more verbose output can be seen with just “git log” of this Repository’s timeline:
This shows the full commit hash output, the Author name / email, Date and Timestamp, and the commit message at the bottom of each entry that details what was committed.
Note that the Hash Value here is much longer than the “git log –oneline” section, because when working with GIT you will only use the first 7 characters in a commit ID Hash when working with other commands for working with the commit Timeline.
Reviewing Commit / Master Branch Timeline and the HEAD of the Master Branch
Speaking of Commit Timeline which is how a Master Branch should be looked at, along with the Head of the Master Branch generally being the last commit, I’ve drawn this up:
I embedded my “git log –oneline” into this MS Paint doc thinking it would be more legible, but essentially what I am illustrating is the “Master Branch” as a time line of commits, which all have their own Hash Value to identify them and more importantly commit comments that I worded very poorly while rushing through labbing!
Next I want to review / demo the Master Branch Head / Detached Head states
The “HEAD” of the Master Branch is illustrated above as the most recent Commit to a GIT Timeline as that is how GIT works, and each new commit will bump the head up to the most recent commit, which I will demo here quick for absolute clarity.
First I’ve created and saved locally a file in Visual Studio Code called “DemoGITFile” :
As noted by the green U this file is currently “Untracked” in the GIT Repo, so I will go over there to manually add it using the GIT Bash Shell:
- “git status” – This shows there is an Untracked file saved in the GIT Repo
- “git add (filename.ext)” – “Stage” the file to Commit to GIT Repository
- “git status” – Shows the new file is now Green / Staged
- “git commit -m “Commit of change to GIT Repo” – Commits not just this file, but this snapshot of the GIT Timeline
- “git status” – Verify nothing to commit on Branch Master, working tree is clean!
- “git log –oneline” – Shows that the latest “Commit” is now the Master Branch Head
Meanwhile over in Visual Studio Code where it previously showed “U” :
Visual Studio Code is very good at syncing with GIT, so the green “U” is gone for Untracked file, and we are good to go with our new “Master Branch Head” in GIT!
Working with a Detached Head from the Master Branch, and what it means to do so!
Detaching the “Head” of the Master Branch is a fun way of saying we are going to move the “Head” from the last commit on the Master Branch where it should be, to a previous commit in our GIT Timeline via a command “git checkout #######” which is the 7 digit Hash Value shown in the “git log –oneline” output (which is why previously mentioned the first 7 digits are how commit points are referred to… for the most part).
I’ve actually created a change to my GIT Repository, so my Head has changed once again, below is a graphic of my Current Master Branch / Head position on the top and where I intend to Detach the Head of the Master Branch and place in within the Timeline:
On the top Branch Timeline with the “Head” on the last commit, the next commit will move it forward on the Branch, which results in the Head being “Attached” to the Branch.
Whereas in the bottom timeline when I “git checkout 9502c01” below, that is going to revert the GIT Repository to that point in time, however Commits will not move Forward from that point as that would overwrite the GIT Repository from that point forward, instead it will create a new Branch off of that Commit point in the Branch Timeline:
It begins making this sort of Psuedo Branch off of that Commit point where you did your “git checkout …” so you can actually make Commits to the code and test it without over-writing your GIT Repository, however once you are done and do a “git checkout master” command that will resume the normal Master Branch Timeline demonstrated at the top of these pictures showing how the Branch will flow.
One big note on this operation – The GIT Repository will appear as it did in that commits “snapshot” of the timeline, so you will appear to lose work, but once you checkout the master Branch again all changes in this Psuedo Branch will go away (but not be entirely gone) and the Master Branch will go back to normal.
The Commits made during this Detached Head state do still create Hash Identifier values so they can be retrieved at a later time, however they are sort of floating around in the Repository, and a cleanup operation ran against this GIT Repo would clean up these files.
Using the “git checkout …” command to Detach my Master Branches Head!
From the picture above I’ve already chosen a point I’d like to jump to called “Script finished” or more importantly by its hash id “9502c01” – Note the change in my visual studio code files when I make this leap in time back to that Commit point.
VSC Files before Detached Head state:
Now to teleport back in my GIT Repo to “9502c01” in the timeline:
We see here that the new “Detached Head” starts at the “9502c01 Finished script” commit, looking at the Status is sows the Detached Head but a clean tree, and looking at the “git log –oneline” output we see past commits still exist in this new Psuedo Timeline created that will now pivot at this head and additional Commits going forward (until we revert back to the Master Branch) will be saved on its own timeline.
Looking back at Visual Studio Code we can also see some changes after this switch up:
PyJSONParsing.py tab is completely missing (file is gone) and the DemoGITFile.txt is now showing as deleted, not sure why the script entirely disappeared while the text file shows deleted but stayed open in a tab, but that is how VSC handled this change.
Now I will create a tracked file called “LostMyHead.txt” and make some changes in it to see how it looks in GIT CMD Terminal as well as VSC here:
I first Staged and Committed the file initially, then added a second line to get a bit of a non-Master Branch timeline going as shown below in GIT CMD Terminal:
Note that it does show that it is making Commits off of the Master Branch that do have their Hash ID / Descriptions, however it does still show in “git status” that the Head is detached at the 9502c01 Commit location, so that we know we are not working on the Master Branch.
While working on a Psuedo Branch, I want to quickly review amending commits!
The command “git commit (filename) –amend “Some Comment”” can be used to update a previous commit if you want to quickly update a previous Commit with say a different Comment or a slight change to the line, it actually replaces the old Commit entirely (bumps it off the Branch) and replaces it with a a new Commit shown here:
What “git commit –amend (filename) …” does it bump the previous commit completely out of the current Timeline (referred to as an Orphaned Commit), meaning that the previous “Head” of this Timeline has been REPLACED by the AMEND and still exists but kind of floating in GIT space in a way that a GIT Repo cleanup would delete the now Orphaned Commit that I have amended here by just changing the Commit Comment.
The huge takeaway – Do not use “amend” unless working in a Lab or Local Repository, as if this Timeline attempted to Merge with a shared Repository it would cause conflicts because the Timelines would no longer match!
This and actually the following commands below that I will demonstrate for the sake of being thorough should not be used on a shared repository, and your probably thinking “well when the heck am are we going to get to GIT COLLABORATION?!” and that will be a separate and very conclusive article from my Cisco Platinum Library training materials!
A quick review of the both the “git reset” and “git revert” commands
I will first use the reset command using what is known as the “Tildy” system which each Tildy # can be thought of as “Hops” in networking, each commit back from the most recent git adds +1 to the value. There are other ways of doing “git reset …” but I am going to use the “Tildy” system here as you can just count back the commits you want to travel.
In this current timeline I want to go back to where the Head was originally Detached where it was “Script Finished” which is 2 Commits backward before my “DemoGITFile” was created so lets see what happens:
This essentially point the head to this “Commit” point in the timeline, and the files will still be in the Repository, however at this point they will all need to be Staged and Committed again as shown here with the single file that became Untracked:
With this the timeline is essentially back to where it was, only now it will look different from the original GIT Timeline, which in a shared repository would cause issues:
I am not sure any case use for it, and I won’t spend any further time reviewing this concept as beyond this example and knowing of the “Tilly” system of GIT Reversion for the HEAD as Hops away from the Head so because it was 3 commits down the history the result was the “git reset” was done to Head~2 (as it was 2 hops away from the Head).
Finally I will take a look at “git revert” which preserves all GIT Repo History
This command is used to simply revert the changes from on the Current Head to a New Commit point in the timeline as I will make a few changes and demonstrate below:
And adding these changes to make several Commits, but that final line to remove interestingly it popped up this new file / message in Visual Studio Code:
Then back in the GIT CMD Terminal:
I highlighted it it hinting that it was waiting for my VSC to be closed for the change to take place, but once I did it can be seen the “Commit Message” for that Head was preserved along with everything else about the GIT Repository except for that extra line that I intended to revert away from when I re-opened Visual Studio Code:
This could come in handy if you make a ton of changes to a script, and something in the changes broke it, and you need to revert back to the version that was previously working quickly, however the Head # is replaced with a new ID Hash value so this again can cause issues in a GIT Collaboration setting.
That will do it for this extremely long GIT post, for those that made it though!
I had just a bit more material that here, but I will end this here, as I am starting to age in front of my monitor and I have some homework to catch up on for week 1 of my DevNet group which ironically is largely GIT 🙂
There will be a separate post next for GIT Collaboration, as this post focused more on the mechanics of GIT but not Collaborating with it between a local Git Repository and GitHub which is absolutely critical to know as a base skill for DevOps.
This material is important as well as the GIT Collaboration material, as you may end up running into / creating many issues collaborating if you don’t fully understand how changes in even the Head ID Hash value can make!
ONE THING I CAUGHT WHILE EXITING DETACHED HEAD MODE FOR EXAM DAY!
While playing with .gitignore (unsuccessfully for right now) I had unstaged / uncommitted, I typed “git checkout master” to get back to my normal timeline and:
If you have “Tracked” files that are in a “Staged” state, the must either be “Committed” or “Stashed” before you can “Checkout” to another point in time (here getting back to Master Branch), which there are a few ways I could have Unstaged these or flat out deleted the file using a few different options:
- “git rm (filename)” – Deletes the file from your system entirely just like in Linux!
- “git rm (filename) –cached” – This will remove the staged file from GIT Cache
- “git commit …” – Just commit them to be able to checkout back to Branch Master
I chose option 3 of just committing the files as my brain is running on fumes at this point, and I got the following message I wanted to document here on my way at, lets check out what it tells us here on our way out of our Detached Head mode:
Yes when I am this mentally exhausted I will just skip editing the image to remove the error and just cross it out and write derp in red 🙂
It tells us we are leaving behind 9 Commits in our Psuedo Timeline, that we may want to keep them by created a new branch with the “git branch … #” with the # I imagine being the last Detached Head Commit from that Branch (I didn’t check the final Head # on my way out as I don’t want to save that branch)
So you may see something like this on exam day, and if you see a graphic with files waiting to be staged, you KNOW that you can’t use “git checkout” until you do something with those files!
With that, I have some homework to get started on my friends!
I have quite a bit of traction to make on my DevNet Guided Study Group to setup my laptop for the class, which includes cloning a DevNet GIT Repository from Github, so kind of depending on keeping up with my class my posts might be fewer and further apart (or more honed in on exactly what the class focuses on).
I will also be making posts not of any Cisco Secrets, but how I better understand the Cisco DevNet Associate exam as I better understand it through this class, so I can have a post reminding both myself and any readers of what to expect on exam day for the DEVASC.
Until next time! 🙂