Determine What Files Changed Between Two Releases

I get asked this a lot. Luckily, Git makes it pretty easy to get this information, but sometimes you need to string together multiple commands to do this gracefully.

Here’s the meat and potatoes:

git diff --name-only REVISION1..REVISION2 desired/sub/directory

What if you don’t have the revision/commit but instead a branch name? And what if that branch name has a / in it? Well, you’ll find that this command fails. It throws a generic ambiguous argument error. How would you get around this? Easy! Find the revision/commit of that branch. How? Check out the branch, make sure it’s the latest revision, and determine the revision/commit ID.

How this can be accomplished in Bash:

git checkout BRANCH/NAME && git pull origin BRANCH/NAME
REV_ID=$(git rev-parse HEAD)

But who added the file and what is the associated work item? STOP MOVING THE GOAL POST! Still, that’s fairly easy, too. Just pull the last commit to each file that’s returned in the diff command. Below is a simple Bash script that will generate this information:

BRANCH_A=release/9.2.0.0
BRANCH_B=release/9.3.0.0
REPO_DIR=/path/to/cloned/repo
CHECK_DIR=sub/path/to/desired/dir

cd $REPO_DIR
git fetch

git checkout $BRANCH_A && git pull origin $BRANCH_A
COMMIT_A=$(git rev-parse HEAD)

git checkout $BRANCH_B && git pull origin $BRANCH_B
COMMIT_B=$(git rev-parse HEAD)

FILE_LIST=$(git diff --name-only $COMMIT_A..$COMMIT_B $CHECK_DIR)

echo "FROM - $BRANCH_A"
echo "TO - $BRANCH_B"
for FILENAME in $FILE_LIST;
do
 echo $FILENAME
 git log -n 1 --pretty=short -- $FILENAME
done
 

Minor Updates

  1. Working on cleaning up KillAllBindings a little. I’ve made some (probably) final changes that I need to test out. Once that’s done, I’m not certain what else I’ll be doing to/with it unless a bug comes up or there’s a need for functionality to be extended.
  2. I’m continuing progress to extending the testing quality of development builds internally while trying to address build speed concerns. Recently I optimized our build process and got build time cut by about 30%. We’re looking at other ways to speed this up all while performing more testing during the build process (which may offset the optimizations, but I’m cool with that).
  3. I’ve started working on a tool that will make source code collection for backing up source easier. It’s called ARC (Archive Released Code) and more information will come as I get closer to completion.
 

Branching Strategy

We’re spending a lot of time discussing our migration from TFS to Git at work. We need this transition to go smoothly. I need this transition to go smoothly. There are a lot of doubters. Yesterday, I was talking to one of our senior DBAs about this and he said “I don’t care, I’m just waiting for it to crumble.” After I told him that I was the one driving this transition, he just sorta wandered off without saying anything else.

This is such a dramatic departure for all of our .NET developers that are used to Visual Studio being a one-stop-shop and I’m worried about backlash when we start making them use another tool (SourceTree since we use Stash).

Anyways, I wanted to go over our current TFS branching strategy and our proposed branching strategy in Git. Or, at a minimum, try to start documenting it.

Main----o---\-----------------o--o
Dev Branches \----o----o----o/       There's a dev branch per team.

The current issue is that Main is used to integrate all of the teams code. As you might imagine, Main breaks. We don’t have a “golden” copy. Additionally, “branching” in TFS is more like a forking operation in Git. A branch is a unique copy of a particular project from some changeset. The major difference is that when you branch in TFS, you’re ONLY getting that one branch whereas in Git, you get the entire repository.

This is what we’re proposing in Git.

Master----o------------------
Integration\-----------------
|
| Fork of "Main" repo per team.
|
Master - - - - - - - - - - - Teams will not use this branch.
Integration\----------------
Feature Branch\----o---o---o-^ Pull Request to merge into team integration branch.

At the end of the sprint, the dev lead will merge their teams integration branch into the “Main” integration branch. All of the other dev teams will need to either rebase their branches when another team commits their code to the Main integration branch or deal with resolving countless merge conflicts.

So, why not branches for these development teams? Well, we discussed this, but the assumption was that we could help keep everyone’s experience as clean as possible so they aren’t sifting through hundreds of feature branches.

What about releases? Hot fixing?

Release-X.y                   /------- We plan to branch and tag this. Potentially branch off of this for HFs??
Master----o------------------o
Integration\-----------------^
|
| Fork of "Main" repo per team.
|
Master - - - - - - - - - - - 
Integration\-----------------o
Feature Branch\----o---o---o-^

Enter fork syncing. Any branch made on the repository that is forked off of will get this branch. In the event of a HF, they will make their fix in their Release-X.y branch and then submit a pull request to have this code merged into the Main release-X.y branch.

Why the hell is release management not merging all this code and resolving conflicts? We’ll, to be frank, there are a couple reasons.

  1. We don’t know the code base.
  2. The assumption that any developer should be able to resolve a conflict simply isn’t true.
  3. The code base is massive and touches so many technologies that no one person can know how it all works (hence #1)

The only time release management will merge code is when we merge into the Master branch or Merge code into a release branch for HFing.

The big benefit to moving from TFS to Git is the ability to enforce code reviews by taking advantage of pull requests. Additionally, we have other development teams that work on mobile apps and Java apps that are already using Git (previously GitHub, now Stash) so it’s be nice to get everyone using the same technology.

Finally, this branching strategy is still in it’s infancy and we’re still toying with it to make sure that it breaks the KISS rule and to ensure that it’s sustainable for everyone. Also, forgive me if I’m using any terms incorrectly, there’s a lot of TFS lingo beat into my head.

 

Removing TFS Source Control Bindings from Solution Files

Today, I started looking into removing the TFS source control bindings from all of our solution files. At the time, I didn’t know how many solution files we had, but I knew it was more than I wanted to go through manually. I did some research online and even found some tools, but they didn’t work correctly for me so I wrote a Python script that would do this for me.

Basically, you edit a single variable, providedPath and run the script. It goes through a directory (and all of it’s subdirectories) looking for solution files. It then goes through each file, finding where they start and end (if they are present), re-writes the file without that section, and replaces the original file. I’ve ran it today, build solutions to make sure I didn’t break anything, and checked that code into Stash. I’ve also build the whole app successfully.

The script is located on GitHub here.

One thing this script does not do that I might add is deleting .vccss files. I didn’t bother with it since I’ve added that file extension to the .gitignore files.

This might grow to do additional things as we test migrating from TFS to Git. My guess is that this will not be the last time I copy all of our source over. Oh, and we have nearly 200 solution files, half of which contain source control binding sections. I’m glad I scripted that.

 

EDIT: I’ve taken the script off of GitHub while I overhaul it and determine if I can actually share it.