Sunday, September 6, 2015

Git Setup and Configuration

Configuring git for KDiff3
Add to .gitconfig (located C:\Users\Tim):

    tool = kdiff3
    prompt = false
[difftool "kdiff3"]
    path = C:/Program Files/KDiff3/kdiff3.exe
    trustexitcode = true
    tool = kdiff3
[mergetool "kdiff3"]
    path = C:/Program Files/KDiff3/kdiff3.exe
    keepbackup = false
    trustexitcode = true

then run it using >git difftool .\folder\Web.config
yes, using quotes to deal with the spaces in program files in .gitconfig file screws it up. Don't use quotes.

Using Console2
Scott Hanselman's blog post
I put a copy of the Console config file in SpiderOak under Dev/Git.

Powershell Execution Policy
Set-ExecutionPolicy Unrestricted -Scope CurrentUser -Force

Making Powershell Readable
add to .gitconfig
    ui = true
[color "status"]
    changed = red bold reverse
    untracked = red bold reverse
    added = green bold
[color "branch"]
    current = green bold
(see copy of config file in SpiderOak)

Credential Caching
Avoid having to enter password (just install it, and it will prompt you once, then you're good)

Getting set up in a new environment (git w/ PShell, PsGet, Posh-Git)
Must-have git aliases

 email =
 name = Tim

Sunday, August 23, 2015


Don't use ASP.NET MVC 4 Web API project template, it has all kinds of non-web service crap in it.

Use "ASP.NET Web Application" under Web, select "Empty" project and check the Web API checkbox. It will register a default route template and if you create a new controller you'll have a working service.

Saturday, August 8, 2015

Monday, January 19, 2015

Git Workflow

git clone
git status
new files will be listed as "Untracked files:" and use git add to put them into the repo as staged
git add *   (stages all, seems to do the same as git add --all)
git add .  (stages new and modified without deleted files)
git add -u  (stages deleted and modified without new files)
git add .\folder\filename.txt
git status tells you how to remove a file from staging:
git reset HEAD <file?
now add to HEAD (has most recent commit on current branch)
git commit -m "message"
commit to remote repo
git push origin <branch>

git fetch origin  (makes the local tracking branch up to date of the current branch, does NOT modify working directory)
git merge origin/master

git checkout dev  (DWIM version that will create a local branch dev and if dev exists on remote it will set up a tracking branch for it.)

gitk .\folder\file.txt  (brings up GUI, then you can copy the hash and do git dc hash#
git difftool .\folder\Web.config
git difftool --dir-diff .\SportsStore\SportsStore  (all changes in this and subfolders, except deletes I think)
git difftool --dir-diff master origin/master  (Will not do anything including not launching diff UI if local matches remote)

Push to master
git push origin master

Summary only (last 5 checkins):
git lsf -5  (uses my alias in .gitconfig)
History of a file (last 5 checkins)
git lsf -5 .\SportsStore\SportsStore.Tests\IocTests.cs
Now you can view the diff by changeset
git dcd f028a41

Branching and Working with Branches
git branch (shows local branches)
git branch -r (remote tracking branches)
git branch -a (remote and local branches)
git branch -vv (lists local branches and their mapped remote tracking branch. If working directory is ahead 3 checkins then it will say that next to the remote branch, and after the remote branch's closing bracket ] it will show the last checkin message from the remote server. All info is based on last fetch from server.)
git show-branch --all  (shows any checkins that are ahead of remote, then the remote branch)

Create a new branch from master
Get local in sync with remote.
git branch dev (does not create a corresponding remote tracking branch, which means another developer won't see it and you can't push to remote using git push --all when in dev branch.)
Then do:
git push -u origin dev. Now other developers will be able to do a git fetch origin and then git checkout dev and see the changes you made in dev branch.

Switching to other branch(es)
If you make a change in master w/out staging it or checking it in and you do a checkout to dev branch, one of 2 things can happen:
1) You will get an error message saying you might lose your changes in master.
2) You will be checked out to dev but the dirty files will now be in the dev branch.
Scenario 2 seems dangerous and I don't know why git doesn't consistently throw an error. Seems a bad choice to just allow those changes into the other branch's working directory.

If I have unstaged or staged files in master and I want to switch to dev without checking in to HEAD my changes in master, I can do:
git stash -u   (stashes unstaged files in working dir)
and now you can do
git co dev  and you'll be good

** caution - doing a stash, then making more changes and doing yet another stash so you have 2 stashes when you do a list can cause problems when you go to pop the second time. You may get a merge error. So don't stash more than once. (well, sort of, I got the error, then did a drop and the untracked file in the first stash got restored. KISS, only one stash.)

git stash pop  (takes latest stash, stash@{0} and restores it. Do it again and it restores the next in the stack)
git stash apply  (caution, I think the stash may persist...)

git stash list   (to see what you have stashed)
git stash drop  (deletes the stash at the top of the stack and you lose those changes, sort of, see caution above.)

if a branch "serverfix" was created by a co-worker and he pushes it onto the server, and you do a [git fetch origin], this fetch creates a reference (this is a remote-tracking branch) to where the serverfix branch is: origin/serverfix. This does not bring any files down that you can work on, you have to do a checkout for that. So at this point, without doing a checkout yet, with the fetch we've only created locally a remote tracking branch for serverfix.
So it's like the relationship I got after doing my clone with master and origin/master. The clone, however did bring files down and at the same time created the remote tracking branch.
git checkout -b serverfix origin/serverfix
-- this will download files from server (origin) and switch (don't know how switch works) to the new branch serverfix. I hope that a new folder is created. I'm sure it does, the "switch" means that git now is in the context of serverfix, not master on the local machine. So if I work on files on my file system that map to master, then (I think) my powershell will not track any work I do there, it is only looking at serverfix changes.
So what the above checkout command does is "checks out a local branch from a remote-tracking branch"

Move to new folder
I had a VS solution that was in c:\TestGit\TestBootstrap\TestBootstrap
This folder had the root of the solution (however the .sln file was in c:\TestGit\TestBootstrap
I wanted to have the new folder structure be c:\TestGit\TestBootstrap\trunk\src
So I added to my local the trunk and src folders with a temp file in there so it would actually get into git.

do a 'git add *' (puts the folders into git staging)

do a 'git mv -n' first for a preview

git mv  -n TestBootstrap/TestBootstrap TestBootstrap/trunk/src
The above command worked from repo root of c:\TestGit.

Don't forget to delete the temp file.

Simple guide
Branches and Remote Tracking Branches
Git: Fetch and Merge, Don't Pull
Everyday Git with 20 Commands Or So
Git in 600 words
Git docs

Test/learning scenarios
Scenario - Check-in Dance:
Branch master is like trunk, we don't work there, we merge changes from dev branch mainly. This scenario says do some work in dev, check it into remote, then merge it to master. Then have co-worker download changes in both.
git fetch origin
git merge origin/<branch>
co-worker does same

Scenario - Undoing:
Undo working directory changes (unstaged changes):
git checkout -- . (replaces working directory with what is in index. Will restore deletes.)
Caution, stashing doesn't play nice with deleted files.
git stash -u
git stash

Scenario - Merge master to dev: Change made in master branch after dev branch was created from master. All changes in both branches are pushed to remote repo. This scenario says we should only work from dev branch, so we need to now merge master up to dev.
~merge master into dev~ dev
git checkout dev
git merge master

Scenario - Conflicts: Two coworkers are totally in sync with remote and have not yet made any changes. Then they both change the same line on the same file and check in and push to master. What happens? How do you resolve this?
So coworker A pushes his change to remote successfully. B commits his but when attempting to push to origin gets an error and it won't let him. So B has to do a fetch and merge and git will tell him there is a conflict and he'll have to resolve it. Whatever the resolution the next step for B is to push to origin and then A can do a fetch/merge.
** But alas, we must always do the check-in dance -- first do a fetch and merge, and deal with the conflict locally.

Scenario - Working in Wrong Branch: I thought I was working in dev branch but instead I was in master and made enough changes to not want to lose them or to manually move them.
So basically, I want to move changes in my master branch working directory to the dev branch working directory.
  • So we are in master branch.
  • git stash list (make sure there aren't any other stashes, or of so, keep track so you know what's what)
  • git stash -u (see above)
  • git stash list (see the new stash
  • git co dev
  • git stash list
  • git stash pop (now those changes get applied to dev)

Thursday, January 8, 2015

Best Practices for Using Strings in the .NET Framework

Use string.Equals()
string s1 = "test";
string s2 = "test";
string s3 = "test1".Substring(0, 4);
object s4 = s3;
Debug.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s2), s1 == s2, s1.Equals(s2));
Debug.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s3), s1 == s3, s1.Equals(s3));
Debug.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s4), s1 == s4, s1.Equals(s4));

True True True
False True True
False False True