Tag: visualizations

How to do a fast forward merge in Visual Studio – 092

Yay!! I’m over 25% of the way into this series!! Which also means OMG is 2017 already 25% over yet?!?!

Today’s tip demos how you can do a straight forward merge in Visual Studio. No conflicts, etc.

Suppose you have have a method called DoNothing() that lives in a donothing branch.

1. Switch to the branch you want as a target

Double-click on the branch name. The bolded name will be the target branch. Checking out the target branch mimics Git command line functionality.

master branch checked out and bolded

2. Right-click the target branch and select Merge From…

Merge From... context menu

3. Click the merge button

We’ll get to what the checkbox means in a bit. As if I could stay away from blogging about a checkbox in VS!  =D

Merging donothing into master

And if all goes well, Team Explorer will give you a message

Repository updated to commit id in Team Explorer status bar

We’ll cover merge conflicts later.

Note this was a fast forward merge because there was nothing to merge, so there’s only the linear graph. A fast-forward is where Git realizes that you could have done each commit on that target branch, so it makes it look like that in graph form.

linear graph in commit history

To visualize what we’ve done in Git, here’s the setup. We have one commit in donothing that’s ahead of master.

branch donothing one commit ahead

Now we checkout master and do a git merge

git merge from donothing into master

Note how the tool assumes it’s a fast-forward merge. The tool must assume this because the tool doesn’t have a concept of a working directory or staging, so it can’t diff any files to detect conflicts. So the tool assumes there are no conflicts, hence a fast-forward merge.

We’ll look at non-fast forward merges next. 

How to create a branch in Visual Studio – 088

It seems that I have to write these tips in triplicate: 1. command line, 2. Visual Studio, 3. git visualization tool. But that’s been the only way to prove to myself I’m grasping the concepts.

Command line

A college French professor once gave me the advice to never use contractions in class unless I was prepared to never ask him to slow down. I had just learned the equivalent of “I do not know” vs “I don’t know” (something like that).

Applying that advice to software, I don’t want to start using git shortcuts by combining commands until it is clear what the two commands are independently doing. (Yep, I’ll show the shortcut in a second… )

First, you’ll want to create a branch:

> git branch my-branch

Next, you’ll want to switch to that branch:

> git checkout my-branch

git branch addColor; git checkout addColor

Git Visualization

Okay that’s pretty straight forward, but what’s happening conceptually?

git visualization of creating and switching a branch

We are on master when we created a branch called addColor while on master and then switched to addColor.

The take home message is that addColor has everything that master has because we created the branch addColor while on Master.

Git Command Line Shortcut

Before we jump into the IDE, let’s take a sneak peek at that shortcut.

Note: in case anyone is following along at home, I first switch back to master to delete the addColor and then recreate using the shortcut.

The shortcut is

> git checkout -b addColor

deleting branch and then recreating using the shortcut

This shortcut says to checkout to addColor and if it doesn’t exist, create it.

Visual Studio

When you’re in Team Explorer, you can go to Branches, right click on the branch you want your new branch to be based on, right-click, and select New Local Branch From…

New Local Branch From... command in Team Explorer - Branches

Then give your new branch a name (and verify in the drop down you picked the correct branch) and leave the checkbox checked…

checkout branch option in Team Explorer

If you have the Checkout branch checkbox, you’re telling VS to create the branch and do the checkout so you’re now on the addColor branch instead of master.

If you uncheck it, it is the equivalent of creating the branch on the command line, but staying on master.

To confirm you’ve created and switched to the addColor branch, you’ll see that addColor is now in bold.

branches showing addColor now checked out

And the branch is also shown in the Visual Studio status bar.

addColor from status bar

How to recover from the "oh no! I did a git reset and now my files are gone!" – 087

If you don’t know about git reflog, your life is about to get much, much better. Prepare yourself. Git is about to make just a bit more sense.

Note: I use the git visualization tool at the bottom of this post, in case you want to jump straight to the “How on earth is this possible?! I give up. Git is just magic.”

Using yesterday’s tip, suppose you have a repo with 6 files each with their own commit.

git bash showing 6 commits

Cool. Now let’s say you did a `git reset –hard <commitID for file4>` to reset back to file 4. Note: any flavor of git reset will work for today’s scenario, since we’re not making any changes in our working directory (or so I think).

To recap these past several days:

  • git reset changes history and should be avoided if you’ve already shared those commits with others (e.g. you use it when you haven’t pushed yet.)
  • git revert undoes a commit by creating a new commit with those changes uncommitted (wow, what a sentence. My apologies.)


Notice how the above image confirms the git log only shows the commits up to file 4.

In addition,`ls` and `git ls-files` shows how files 5 and 6 are “gone”!

ls and git ls-files not showing files 5 and 6

will the real Git Log please stand up? please stand up. please stand up.

The command`git reflog` will show you the actual history of your git commands AND THEIR COMMIT IDS!!

output of git reflog

what?! what?! what?!

The lightbulb moment for me was that git was keeping those commits around, and not to mention git is also keeping an actual log of everything going on alongside my repo’s git log.

Let’s get those files back.

You’re going to do another git reset, but this time, you’re going to change history by rolling forward instead of rolling backwards.

so you’ll do `git reset –hard <commit id for file 6>`

git reset --hard commitID showing files 5 and 6 come back

and all our files are back. In fact, if we do a `git log` we’re back to where we were at.

git log showing all commits back

How on earth is this possible?! I give up. Git is just magic.

Let’s learn some magic tricks using the git visualization tool at http://git-school.github.io/visualizing-git/

alrighty. let’s rinse and repeat the setup

git visualization showing head and master at file 3

notice how the commits for files 4, 5, and 6 are there, but just dotted out (or whatever the official term is).

So we never “deleted” those commits. We just told git to hide them from ourselves, but not from git.

Now for the magic. We can do a reflog here in this tool.

using git reflog and git reset back to file 6 in tool

Notice how HEAD and master pointers just move back to that commit ID. That’s it. These HEAD and masters pointers are just that… pointers.

This is why people say “don’t delete your .git folder and start over.” Your changes aren’t “gone”. They are just playing hide and sneak because you told them to.

Got to  get back. Back to the past. Samurai Jack!!

How to fix the "oh no! I’ve accidentally committed on master instead of a branch" – 082

If you haven’t seen http://ohshitgit.com yet, stop reading this blog series and go check out that site, then come back here. I’m going to play out this scenario using the Visualizing-Git tool from yesterday.

I need to print this out this accidental-commit-master section and have it laminated on my desk. How many years have I gone to work, fired up Visual Studio, and started typing? And now all of a sudden I have to create a new branch first? I feel like this is the pilot equivalent of having to lower the landing gear before taking off. Nah, I don’t regret my career/life choices at all!

As my above drama illustrates, you’ve been coding along on a new feature and then you realize, “oh no! I’m still on master!” What I’ve done for years is Ctrl+C, Ctrl+V, diff my changes, delete either the last commits and/or working directory, and then create the branch and move over my changes. At least I’m being honest.

We’ll follow these steps from ohshitgit.com via command line. But don’t stress if it doesn’t make sense. Once we rinse and repeat from Visualizing Git, it will make much more sense!

Part 1 – Command Line to the rescue!

Let’s say you’ve been working, working, working on your code, and suddenly you realize all these files you’ve added have been to master instead of a new feature branch!

 git log w 6 files added to master

First, don’t panic. Take a deep breath and don’t delete anything 🙂

Next, create a branch (git branch branch-name), but don’t check it out, so no `git checkout -b branch-name` shortcut!

git checkout feature-work

Now do `git reset –hard <commit ID to roll back to>`, e.g. I want files 1-6 added to my feature-work branch, so I’ll use the commit ID for the readme.

Note: since you are using the –hard, in the future, you’ll need to make sure that you don’t want to keep anything in your staging or working directory.

git reset --hard commitID

What?? Is our work gone?? There’s no commit logs for files 1-6. and doing a `ls -la` or `dir` or a `git ls-files` only shows the readme!

It might not seem like it but our work is still there. To quote my inner matrix, “the answer are coming.”

Now finish this by checking out the branch…

checking out the branch brings back the commits

WTF? Don’t give up. The answers are coming. I promise. (This is a conversation I would have had with myself from a week ago.)

Part 2 – Visualizing Git to the rescue’s rescue

Okay how on Earth did that work? Let’s rinse and repeat using the Visualizing Git tool.

First I’ll commit a readme and then 6 files.

inital setup visualization

now we’ll create that branch, but don’t check it out!

created a new branch

Remember that a branch is a pointer. Reminds me of a high school teacher who said “A logarithm is an exponent” over and over and over again in hopes we wouldn’t panic when we had to deal with logarithms in the future.  

But now we can see that the branch points to where master (another branch) is pointing. This is my ah-ha moment! In my mental model I’ve been visualizing a branch as a collection of commits from some starting point to some ending point, but here I can clearly see it is just pointing to the last commit I created it at.

Now let’s break down`git resert –hard commitID`

  • git reset means that it is moving where the current branch is pointing at (aka the tip) back to some previous commit.
  • — hard means Git will reset both staging and working directory to the changes you’re resetting to, so make sure `git status` is clean
  • some instructions show HEAD~. HEAD is a pointer as shown in the illustration. HEAD~ means move back one commit (HEAD~1 does the same as HEAD~). But since we want to remove all the files from master and not just file 6, we’d either have to do commitID or HEAD~6. CommitID is just easier to follow in this example.

When you type in `git resert –hard <commitID-for-readme>` you’ll see the following:

git reset --hard <commitID-for-readme>

Now things are making A LOT more sense. The feature-work pointer still points to all of our work since we’re only moving the tip of the master branch back.

and for the grand finally, you can now switch to that branch.

git checkout branch

And just to finish this all off since we’ve come this far after all, you can either do a merge (which will automatically do a fast-forward because no conflicts) or if you want to show that this work was always on a branch, you could do 1. `git checkout master` and 2. `git merge –no-ff feature-work`but we’ll talk about this in future tips.

non-fast forward merge of feature-work branch