Git and our friction points and beginners mistakes

Introduction

A couple of days ago I posted an article talking about our migration from SVN to Git. During our first handful of days working with Git our team found several friction points hindering our daily work flow and we all did some things really wrong. But com’on after all we are learning, right?

In this post I want to share some of our findings.

Where is my blame feature?

Working with SVN and the Visual.SVN plugin for Visual Studio one can right click in any code file and call blame. A really handy feature. How can we do such a thing in with git without having to type a lot? First possibility is to use the git blame command. But this needs a lot of typing if the relevant file is located in a highly nested subfolder.

git blame /subfolder1/subfolder2/subfolder3/FileIWantToBlame.cs

not very wrist friendly I want to say.

Second way is to use gitk. Type gitk in the bash shell and right click on the file you want to blame and select “blame parent commit”. But this only works if the file has been modified otherwise it is not available in the list of changed files and thus cannot be accessed.

I wonder whether there is not a easy way to blame directly from within Visual Studio? Any suggestions…?

Help, I have merge conflicts

When merging or rebasing we might run into merge conflicts that cannot automatically be resolved by git. We can then just call git mergetool

$ git mergetool

merge tool candidates: tortoisemerge emerge vimdiff

Merging the files: build.rb

 

Normal merge conflict for ‘build.rb’:

  {local}: modified

  {remote}: modified

Hit return to start merge resolution tool (tortoisemerge):

to manually merge the conflicting file with one of the suggested tools. If we want to permanently define which tool (e.g. tortoisemerge) we want to use we can do this by updating our configuration with

$ git config –global merge.tool tortoisemerge

now each time we type git mergetool the Tortoise merge tool is automatically opened.

Git reflog

A coworker called me this morning and said to me something like: “Yesterday night before leaving I committed all my changes to my working branch but this morning they are all gone…”. Digging a little bit deeper we found out that my coworker after committing to the local working branch pushed to the backup and as a first thing in the morning pulled from the backup.

Well I said, first of all you should not need to pull from your backup except in case where you lost your local repository due to e.g. a hard disk crash or the like. On the other hand if the backup repository would really be up to date then a pull should not have changed anything, right?

What can we do now? We analyzed the log but the last entry that showed up was about 4 hours earlier than the one that my coworker did before leaving… where did the about 3 other commits go?

After googling around we found out that git reflog might help in our situation and indeed this command showed us exactly what happened. We also found our missing commits. Hurray!

Using this command you get something similar to this

image

Now we can use git reset to go back to any desired point in the history (and thus undo “unwanted” changes). In our case I saved the day by using this command

git reset –hard HEAD@{5}

and my coworker was happy again….

Git and changing the database schema

When using Git as your SCM it is normal to work for quite a while – maybe for a couple of days – in a local branch and without ever pushing the changes to the origin. Usually we only push when a feature is done or a defect is completely resolved.

When implementing new features or user stories most often database schema changes are needed. We have an inhouse database schema and data migration tool that we use for this job. Each developer writes migration scripts as she is changing the schema or the (baseline-) data. Now these scripts have to follow a naming convention such as that they start with a 4-digit number and are sequential (without holes). In a distributed system it is now more difficult to maintain this numbering convention. Furthermore it is more likely that we will also have database schema conflicts.

We do not yet have a good solution for this scenario.

I’m in the wrong directory baby

This happened to me once: I was navigating to a sub directory of my local Git repository and didn’t realize that I was still in that sub directory when I did my next merge. Although I had used the –A option with git add I still had untracked files after the commit.

The problem was that the untracked files were in another branch of my repository in relation to my current location. Lesson learned: Always do your usual git operations in the root of your repository.

Backing up my local repository

Since we are going to work locally potentially for days without pushing to the origin (our central repository) we might well loose our work if we have a hard disk crash or our office is flooded. Thus we need some backup strategy. We decided to use backed up network folder to do the job. Each developer has a folder on our internal SAN which he attaches as a network folder (e.g. as a g-drive). Then we use the following command to copy a clone of our local repository to the network drive

git clone –mirror repoName g:/repoName.git

To make life easy we define an alias for the backup repository

git remote add backup g:/repoName.git –mirror

and we can now save our changes at any time by simply typing

git push backup

in the command shell.

The backups created with the –mirror options do contain all branches and their commits in the repo. We can do a git push backup and this will mirror all changes to all branches regardless of our current branch.

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Gabriel Schenker

Gabriel N. Schenker started his career as a physicist. Following his passion and interest in stars and the universe he chose to write his Ph.D. thesis in astrophysics. Soon after this he dedicated all his time to his second passion, writing and architecting software. Gabriel has since been working for over 12 years as an independent consultant, trainer, and mentor mainly on the .NET platform. He is currently working as chief software architect in a mid-size US company based in Austin TX providing software and services to the pharmaceutical industry as well as to many well-known hospitals and universities throughout the US and in many other countries around the world. Gabriel is passionate about software development and tries to make the life of developers easier by providing guidelines and frameworks to reduce friction in the software development process. Gabriel is married and father of four children and during his spare time likes hiking in the mountains, cooking and reading.
This entry was posted in Git, Workflow. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Peter Lehmann

    well i am not 100% sure but i think Git extensions can give blame i visual studio, check the project out at http://code.google.com/p/gitextensions/

    i only use it for log as it is a lot better then gitk

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    Rails migrations use a timestamp like:

    20100618102835

    yyyyMMddhhmmSS

    We automated the generation of our change scripts through NAnt and RedGate SQL Compare (which has a command line tool). If you don’t have that, you can create a simple script that generates an empty SQL file with a name and the current date, like:

    genSql.bat My_Desc_of_change

  • http://www.lostechies.com/members/gnschenker/default.aspx Gabriel N. Schenker

    @bogardj: Jimmy, thanks for your suggestion. But in the mean time we came up with another solution that will work for us. I’ll probably have another blog post about this

  • Ike

    git commands from within vs.
    I haven’t tested this myself (I’m not using git).

    http://gitscc.codeplex.com/

  • http://paulbatum.com Paul Batum

    I can confirm that git extensions will give you easy access to blame from within visual studio. Its pretty much the only reason I have git extensions installed.

  • Mike

    On the backup to your g: drive, do you include the source files as well? I tired the above and had to use –no-hardlinks option to push the source files to my own g: drive.

  • http://www.lostechies.com/members/gnschenker/default.aspx Gabriel N. Schenker

    No, on the backup there is only the repository (the .git folder)

  • Mike

    OK. I was surprised when I cloned the G: drive back to the C: all the source files were there.

    Great article.

  • Amit

    I am getting error while taking mirror backup of my local repository.
    I trying to take backup into virtual machine from window machine.
    C:UsersAmitDocumentsGitHub> git clone –mirror .repository_name
    username@remote_id:pathrepository_name

    fatal: Could not switch to ‘username@remote_id:path’: Invalid argument