Tuesday, September 24, 2013

git-tf : Finally Got It Working with TFS

If you have a mixed computing environment (Windows and Mac) and you want to keep all your source in Team Foundation Server, then you'll most likely use Git-Tf to checkin your git commits into TFS and pull from TFS into git. 

Note: some of this post is copied directly from other sources to preserve clarity, but none of the other sources provided enough of the detail for a beginner to git-tf like me.  So I decided to combine all the separate steps into a single walk through. 

Here's what I had to do after scouring the net for partial solutions:

Assumptions:

  1. You already have TFS up and running and have created a blank project/folder for your iOS source to be committed into.
  2. You have already connected your iOS project to git locally (I am not paying for a private git repo, nor would I want to share this project publicly   All the git commands are working at the local repo on my Mac (except the very last one, "git push". I tell you about it, but I don't actually use it, since I'm not publishing my git repo to the world)

In order to check-in your existing xCode project code into TFS:
  1. On your Mac, download and extract Git-TF. I placed it in /users/{yourloginaccountname}/Git-Tf
  2. Create the .profile file:
    1. Open Terminal and type in "cd ~/" to make sure you are at your home directory.
    2. Create the .profile file with the following command: "touch .profile".
    3. Open the .profile file with the following command: "open .profile".
      1. The Open command will use the default editor, but you could alternatively use nano to edit the file as well: "sudo nano .profile".
  3. Either way, you need to then make sure you have added the following text into the .profile file:
      • export JAVA_HOME=/Library/export JAVA_HOME=/Library/Java/Home
        • export PATH=$PATH:$JAVA_HOME/bin:/git_t
          • export PATH="/Applications/Xcode.app/Contents/Developer/usr/libexec/git-core/":$
            • export PATH="/Users/{yourloginaccountname}/Git-Tf/":$PATH
            1. You could just run the above commands one by one in the terminal app as well, but I prefer that they are in the .profile file that gets merged with the $PATH when you start the computer.
              1. But the above is the generic version that you can use.  Notice that the only thing you need to change is the {yourloginaccountname} in the last line, if JAVA is installed in the /Library/Java/Home directory and /Users/{yourloginaccountname}/Git-Tf is really where you installed Git-Tf.
            2. Make sure the double quotes in the lines above (last two commands) are really double quotes and not the curly double quotes which translate to a different character and will not work!
          1. Save the file and close it.
            1. If you are using nano press "Control-x" then press "y"then enter, then press enter again to save the file. (look at the commands at the bottom of the terminal to see this.)
          2. Now still in terminal, change the working directory to your xCode project folder: e.g.:
            cd "/users/{yourloginaccountname}/documents/xCode Projects/testproject1/" Wherever your project lives on file.
          3. If you show all hidden folders & files, you will see the hidden .git folder – this is your projects GIT repository folder. If this folder doesn’t exist, you don’t have GIT setup with your project – read this post to find out how to create one.
          4. Run Commands:
            • For a team working with an existing Git repo, a developer sharing changes to TFS using Git-TF would use the following workflow.
              1. git tf configure http://myserver:8080/tfs/YourCollection $/Projects/Development/Mobile/iOS/iPhone/ 
                Configure the existing repo's relationship with TFS
              2. git tf pull 
                Fetch the latest changes from TFS and merge those changes with the local changes. Note, merging is important when working in a team configuration. See "Rebase vs. Merge" below.
              3. git commit -a -m "merge commit"
              4. git tf checkin
                Check in the merge commit as a single TFS changeset
                • This step game me some problems.  During the checkin, TFS will create a temporary workspace before actually commiting the files.  git-tf will attempt to acuire a lock on the project directory, if it fails (due to some one else having a file checked out) then follow the following steps:
                1. Open Visual Studio 2010
                2. Open the "Team Explorer" tab, you may need to add this tab if you don't have it added already.
                3. Click "Pending Changes" to open the pending changes view.
                4. Click on the drop-down list labeled "Actions" and choose "Manage Workspaces".
                5. Down at the bottom of the "Manage Workspaces", click "Show remote workspaces".
                6. You should then see a workspace with the name like git-tf[some-big-number].  Select it, then delete it.  This will not change your workspace at all, but it will remove the locked workspace.  Once you delete the remote workspace, you can then run the checkin again:
                7. git tf checkin
              5. git push
                Push the merge commit to the origin
                • You only need to use the git push command if you are publishing to a free public git repo or are paying the $7 monthly subscription for a private git repo and you are intending to share the repo with multiple developers.
          5. If you get prompted to install Java in step 5 – do it. Then re-run the command.
          6. Now if(when) you get a java security exception, you will have to install your TFS SSL certificate and register it with JAVA so GIT-TF can talk to your TFS. You will only have to do this once.

              1. Download this InstallCert.jar: I put it inside the Git-TF folder – but it could go anywhere.
              2. In terminal, CD to the folder where you downloaded the .jar file. Then run the command:
                java -jar InstallCert.jar  https://yourtfswebaddress.com/tfs/gittfs
              3. This will create a file “jssecacerts”. Put this file in/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib (your java version may vary)
              4. Rerun the commands in step 5.
              5. Your code should now be in TFS
          How to pull down the code from TFS (if you don't have the project and want to get it for the first time):
          • Steps are nearly the same as above, after installing Git-TF and establishing the path variables, CD to your project directory, and run the command: 


            1. git tf clone http://myserver:8080/tfs/YourCollection $/Projects/Development/Mobile/iOS/iPhone/ 
            • Changes are cloned down from TFS to git


          And Just to Be complete: Individual Developer with a New Repo
          A typical workflow for an individual developer using the Git-TF tools are as follows.
          1. git tf clone http://myserver:8080/tfs/YourCollection $/Projects/Development/Mobile/iOS/iPhone/ 
            Changes are cloned down from TFS to git
          2. Make changes to the file in the Git repo
          3. git commit -a -m "commit one" 
            (commit changes locally)
          4. Make more changes
          5. git commit -a -m "commit two"
          6. git tf pull --rebase
            Fetch the latest changes from TFS and rebase master on top of the fetched changes.  You should research the difference between rebase and merge.  Rebase has potential issues if you are working in a team environment.
          7. git tf checkin 
            Check in the changes from "commit one" and "commit two" as a single TFS changeset

          Friday, June 14, 2013

          SQL - Check Multiple Tables For Data (IF NOT EXISTS) in a Single IF Statement

          Question:  How do you check for existence (IF EXISTS or IF NOT EXISTS) of data across multiple tables in a single if statement in SQL?

          Answer:
          IF NOT EXISTS (SELECT 1 FROM Table1) AND NOT EXISTS (SELECT 1 FROM Table2) AND NOT EXISTS (SELECT 1 FROM Table3)
          BEGIN
          PRINT 'DATA DOES NOT EXIST'
          END
          ELSE
          BEGIN
          PRINT 'DATA DOES EXIST'
          END