Month: March 2017

How to fix the "I’ve started making changes on master. How do I get those to another branch?" using Visual Studio – 090

For 20 years, Visual Studio users have started their workday by launching VS and start coding. Now we have to break that “muscle memory” by stopping to think, “Hmm which branch am I on? Do I need to switch branches first?”

You are allowed to switch to a branch, provided that branch doesn’t already have different changes to the same file. You’ll see the happy case, then the #sadtrombone case.

Help wanted:  This tip is only for saved changes, *not* committed changes. I don’t know how to undo the “oh shit! I’ve committed on master!” *from within Visual Studio* without dropping to the command line. If someone knows, please share in the comments or on twitter! aka please get my attention – references to Samurai Jack seem to work very well 🙂

Happy Case

Suppose you have a Console Application and you need to add a new file called IDoNothing.cs – yep, how I roll.

IDoNothing.cs being added in Changes window

Note that I haven’t committed anything else. These files are only saved.

Team Explorer will still allow you to switch branches. Go to Team Explorer – Branches, and switch to the desired branch.

donothing branch switched to

Then you can commit your IDoNothing.cs file into the donothing branch.

#sadtrombone case

From a previous tip, we’ve made changes to the output in our decorations branch. So let’s switch back to master and make some changes to Program.cs, e.g. adding a new method call.

DoingNothing() method added to Program.cs

We’ve saved the changes, but haven’t committed them. Now when we try to switch to decorations branch we get an error message.

error message: cannot switch becaues uncommitted changes

Yes, that reminds me of the old joke about the helicopter that’s lost over Microsoft HQ. When they the folks on the ground where they are at, they hear, “You’re in a helicopter.” The pilot says, “Thank you!” and plots a new course. The passenger says, “WTF? How do you know what to do after that answer?” He said, “it’s clearly MSFT. You ask a question and get the most technically accurate, but yet not really useful for the given situation answer back.”

Yes, true, you cannot switch because of uncommitted changes, but why is this different than before? Because decorations branch already has a different Program.cs file than what’s in our current branch (master).  In the happy case, by adding a new file, I knew there would be no conflict (and given it’s a Console Application, i don’t have many options for a demo 🙂 But when modifying Program.cs, there’s a conflict, so VS says to see Output Window for details:

> Cannot complete the operation because of existing changes to the following file:
    ConsoleApp1/Program.cs

Now that’s a useful answer! 🙂

How to commit and visualize code on different branches in Visual Studio – 089

Yesterday’s tip visualized what happens in Visual Studio (and in Git) when you create a branch. Today’s tip visualizes committing code independently in different branches.

First, you’ll see how to commit to separate branches in Visual Studio, then we’ll rinse and repeat in the Git Visualization tool.

Committing to Different Branches in Visual Studio

In this example, I’ve rolled back to the Console Application with only output message. We’re going to add the ChangeColor() method and call on a branch called addColor.

ChangeColor() committed to addColor branch in Team Explorer

Once you’ve pressed Commit All to addColor, you’re going to discover that you want to experiment with decorations. You can use Team Explorer – branches to create a new branch called decorations.

You’ll want to use master because you want to keep the addColor changes separate from your decorations branches.

Creating a new local branch from master in Team Explorer

and you’ll want to verify you were on master in the dropdown

creating branch from master called decorations

Add your decorations to your project file

adding more output decoration text

And now commit those changes to your decorations branch.

committing to decoration branch

And now we have 2 different commits on 2 different branches

3 branches in Team Explorer

Visualization of what we just did

First, we’ll want to create and checkout a branch called addColor and make some changes there.

git commit, checkout -b addColor, commit visualization

Next, we’ll want to switch back to master and create a new branch from there.

git checkout master, git checkout -b decorations visualization

Finally, we’ll make a commit on the decorations branch.

git commit on decorations branch visualization

I keep trying to remind myself that whenever I do a checkout, reset, etc. I’m not really going forward and backward in time, but rather I’m moving to a different nodes on a graph. Visualizing what git is doing helps break my timeline mental model.

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.)

image

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!!