Friday, July 6, 2012

Some Bash tips from others

I'm mostly a Windows guy. All my computers are loaded with Windows. I know how to use *nix, though not very efficiently. Since I started using Git, I have to deal with Bash more and more, through MinGW. Thus it's better to pickup some tricks of Bash to work more efficiently.


  1. !$: will be replaced with the last parameter to the last command. For example, if you just executed a command like this:
       ls /a/very/long/path
    and then you want to know the detail of what's in the path, a simple way of doing it is:
      ls -l !$
    If !$ is modified with :h, then the last part of the path is removed.
  2. ^: leading ^ will start replacing last command line with something new. Coming from last example, if part of the path is wrong, then you can try this:
        ^wrong^correct
More info can be found in this link: http://samrowe.com/wordpress/advancing-in-the-bash-shell/

Monday, June 11, 2012

1st try on VS2012

After several hours download and installation, I finally can start trying the RC. From first sight, I really can not say I like the UI. Too much change and all black-white icon really make it hard to find the correct icon. Luckily I'm mainly a keyboard guy and does not use toolbars often. With R# EAP version installed, I don't really need to even drop down the stupid all capital case MENU. BTW, install the removeCAPS extension can help you easily turn it back to normal.

There are things I like about it. Even it's not released version, it's really stable, and the responsiveness is much better than VS2010. Also I can work with VS2010 solution file and project files without any problem. This is a must have feature for try out on projects you share with team.

Thursday, May 10, 2012

MSysGit mergetool broken after 1.7.7

I've been using Git on Windows (MSysGit) happily with BeyondCompare 3 for quite a while. Mostly I use BC3 to view changes. Occasionally I use it to merge conflicts. I don't merge very often, thanks to Git's powerful merging capability. It has worked fine. Recently I upgraded to version 1.7.10-preview20120409, and suddenly the git's merge command always fail with below error messages:

Merging:
my/path/filename.cs

Normal merge conflict for 'my/path/filename.cs':
  {local}: modified file
  {remote}: modified file
Hit return to start merge resolution tool (BC3):
git_path/libexec/git-core/mergetools/BC3: line 9: bcompare: command not found
my/path/filename.cs seems unchanged.
Was the merge successful? [y/n] n


Where is this line 9? It turns out that it seems MSysGit (or Git?) has put all merge tools to a folder named "git_path/libexec/git-core/mergetools/". In my installation, I can already find quite a bunch of tools:

araxis
bc3
defaults
deltawalker
diffuse
ecmerge
emerge
kdiff3
kompare
meld
opendiff
p4merge
tkdiff
tortoisemerge
vim
xxdiff


and they are actually bash scripts. For example, the bc3 file is like below:

diff_cmd () {
 "$merge_tool_path" "$LOCAL" "$REMOTE"
}

merge_cmd () {
 touch "$BACKUP"
 if $base_present
 then
  "$merge_tool_path" "$LOCAL" "$REMOTE" "$BASE" \
   -mergeoutput="$MERGED"
 else
  "$merge_tool_path" "$LOCAL" "$REMOTE" \
   -mergeoutput="$MERGED"
 fi
 check_unchanged
}

translate_merge_tool_path() {
 if type bcomp >/dev/null 2>/dev/null
 then
  echo bcomp
 else
  echo bcompare
 fi
}


and there is really is a line 9! Of course directly modify the file will do the trick. But I guess there are better ways. After testing around, trying to override the merge_tool_path environment variable, I found it's easier if I just put BC3's folder to path, and nothing else need to be changed!

Friday, May 4, 2012

Git: generate patches, after or before commit happens.

Occasionally, if not often, I need to generate patches to be applied to another git copy. This can happen either before I commit or after. It turns out, the ways to do it for the two scenarios are different.

If the change set is already committed, then below command line can generate the patch:



git format-patch -1

This will create a patch in the current folder with file name like 0001-comments-in-the-commit.patch.

-1 in the command line means generating patch for last one commit. If you want to patch in more commits, specify the number here. If you don't like the default file name and want to specify your own output file name, then you can direct output to stdout and the redirect stdout to a file, like below:


  git format-patch -1 --stdout > your_file_name.patch

So how do you do it when you don't want to commit the changes? A simple way is to generate the diff output and redirect it to a file. The problems is, like most people, I'm not satisfied with git's diff output and I use a graphical tool, BeyandCompare, to do the diff viewing. If I execute

git diff > pathfile.txt


the BC is invoked and there is nothing redirected to the patch file, unsurprisingly. So how to force the diff command to skip the GUI tool? As in most of the cases, a command line switch comes to help: --no-ext-diff. Below command line will happily output the result to console and skip BC:

 git diff --no-ext-diff Applying patches generated with git diff is simple:
patch -p1 < patch-file.txt

Tuesday, February 14, 2012

git diff: ignore the deleted files and newly added files

I have a project that has gone through some serious refactoring, during which a lot of garbage files were removed. Then during a code review, the HEAD was compared with the last release tag and bang!, BeyandCompare UI was popped up so many times that we had to abort it after a while.


git diff sha-for-pre-release


Then I though there must be a way to skip this and it turned out there is. When using git diff, there is an option, --diff-filter, among tons of others. And below are excerpted from the manual:


--diff-filter=[(A|C|D|M|R|T|U|X|B)…[*]]
Select only files that are Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R), have their type(i.e. regular file, symlink, submodule, …) changed (T), are Unmerged (U), are Unknown (X), or have had their pairing Broken (B). Any combination of the filter characters (including none) can be used. When * (All-or-none) is added to the combination, all paths are selected if there is any file that matches other criteria in the comparison; if there is no file that matches other criteria, nothing is selected.


My favorite option is --diff-filter=MRT, which will skip added and delete files.

Saturday, February 4, 2012

Configurations of application using IoC, Spring.NET

I have being using Spring when I worked in Java world. Now that I'm in C# part of the world, I'd naturally go with Spring.NET. To be honest, before using Spring.NET, I did not even heard about StructureMap, Windsor, Autofac, NInject, let alone the Funq, Munq, Light.Core, etc. In general, I could live with XML configuration, and some configuration feature derived from XML really makes passing configuration data much easier, by putting below object definition in the container, you can isolate your often changed settings to a file without writing any glue code:

  <object id="SYSTEM.ConfigPropertyHolder" type="Spring.Objects.Factory.Config.PropertyPlaceholderConfigurer, Spring.Core">
<property name="LastLocationOverrides" value="true"/>
<property name="ConfigSections" value="config.app"/>
<property name="Locations">
<list>
<value>~/Config/config.app.xml</value>
</list>
</property>
</object>



now I can use a file named "config.app.xml", in folder Config, to hold my config settings:


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="config.app" type="System.Configuration.NameValueSectionHandler, System" />
</configSections>

<config.app>
<add key="value1" value="some data" />
<add key="value2" value="other data" />
...
</config.app>
</configuration>



and in the container definition xml file, I can use the settings defined in the config file:

  <object id="obj_id" type="type.name">
<constructor-arg name="para1name" value="${value1}"/>
<property name="pro1name" value="${value2}"/>
</object>



And since most of Spring.NET's objects are defined with an id, there is even a further way to do the customization, using another class "Spring.Objects.Factory.Config.PropertyOverrideConfigurer, Spring.Core". Put such an object definition in container,


<object id="SYSTEM.ConfigPropertyOverride" type="Spring.Objects.Factory.Config.PropertyOverrideConfigurer, Spring.Core">
<property name="IgnoreResourceNotFound" value="true"/>
<property name="ConfigSections" value="config.system"/>
<property name="Locations">
<list>
<value>~/Config/config.sys.xml</value>
</list>
</property>
</object>



you gain the capability to directly change object properties in config.sys.app:

  <config.system>

<!--the key must be a <object_in_context>.<property>-->
<add key="obj_id.someProperty" value="12345"/>
<add key="another_obj.anotherProp" value="good!"/>
...
</config.system>



Ugly or not, it's really convenient and powerful. In general, Spring.NET is really a feature rich software package, not only a IoC container. And also the document is really good, comparing to most other OSS projects.

So what's the problem? The problem is I'm getting more and more tired with the angle brackets, and I would like to try something new, like NInject, Autofac.

Thursday, February 2, 2012

SubWCRev.exe and its dependencies

Our team is using Subversion as CVS, and thus it's natural to use SubWCRev.exe to retrieve source code version and embed into VersionInfo.cs file, so we can already rebuild the software when we get a bug report.

The problem is when the build process is running on build server, there is no TortoiseSVN installed on the server and I don't want to install it on all the build agents. So I took some time to find out the dlls that SubWCRev.exe depends on, in case I forget it:

# intl3_tsvn32.dll
# libapr_tsvn32.dll
# libaprutil_tsvn32.dll
# libsasl32.dll
# libsvn_tsvn32.dll