Splitting Repository Subfolder / Subdirectory in GIT

I had a GIT repository that I wanted to structure differently.  I have also used this this same technique for splitting up their repositories into submodules.

The quickest approach, in my mind, was to first split out the history of a folder into a new branch:

  • git subtree split -P <name-of-folder> -b <name-of-new-branch-to-store-history>

After that go and create a new repository and pull in all the history from the folder:

  • git init
  • git pull </path/of/original repo> <name-of-new-branch-created-above>

Done with that repository.

Now back in your “original” repository you may want to clean out the history of that folder OR you may not.  In one case, I left the history alone and just deleted the folder.  In another I cleaned out the history because I thought it was redundant for that particular case.

To filter out a folder in the larger/original repository:

  • git filter-branch –subdirectory-filter <folder> — –all

Hope it helps!

fatal: C:\Program Files\Git/libexec/git-core/git-pull cannot be used without a working tree.

You might also see: git-pull cannot be used without a working tree

When executing a pull you see something like this:

1
fatal: C:\Program Files\Git/libexec/git-core/git-pull cannot be used without a working tree.

To Fix:

Check under:

1
\.git\config

Under the [CORE]

1
2
3
4
5
6
7
8
[core]
repositoryformatversion = 0
filemode = false
bare = false
logallrefupdates = true
symlinks = false
autocrlf = false
worktree = &lt;&lt;&lt;&lt;&lt;&lt; DELETE THIS LINE!!

Change GIT Editor

By default the git commands that require an editor would use ‘vi’, but if you can add an entry into your global git config to change the editor to Notepad++. To change to some other editor such as Notepad++ or Textpad you can add these lines to the global git config.  For example:

[core]
   editor = '/C/Program Files (x86)/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin

OR

[core]
   editor = '/C/Program Files (x86)/TextPad 5/TextPad.exe' -m

Either edit the global config manually or you can run this git command

git config --global core.editor '/D/ProgramFiles/Notepad++/notepad++.exe -multiInst -notabbar -nosession -noPlugin'

NOTE: If your editor path contains spaces you could have trouble running the above git command. Recommend to just edit the global config directly in that case to ensure the editor gets added correctly.

Git and Submodules

We were looking at using submodules to store all of Windchill code. Currently it is around 10 million lines of code in over 400+ modules. It seems to make sense to have every module a git repo even though some modules are quite small.

I was curious though if when using git submodules we could still have a quick response to the question, “What did I change?”. If you ran “git status” in the super module it responds rather quickly with the modified submodules. Unfortunately it does not respond with the names of the files changed. It wouldn’t be performant to do a git status in each submodule, especially when you know right away which submodules changed. So that is where this script comes in handy.

1
alias cdv="cd /f/Git_Module/git_super_module"
1
2
3
4
5
username@localhost /f/Git_Module/git_super_module (master)
$ function sstat { cdv; for m in $( git status -s | grep -E '^ M' | cut -c4- );
do if [ -e $m/.git ]; then cd $m; ( git diff --name-status HEAD; git ls-files
-o --exclude-standard | sed -e 's/^/A /' ) | sed -e "s,\s, $m/,"; cdv; else ech
o $m; fi; done; }
1
2
3
username@localhost /f/Git_Module/git_super_module (master)
$ sstat
M Folder/Where/File/src/loadFiles/customization/fileModified.xml

Awesome! So now we can see which files were modified in a few seconds (on linux this is less then a second). That is pretty sweet.

Until next time.

Git and Notepad++

Simple but really helpful if you want to use Notepad++ as your default editor when using GIT. The location will depend upon your specific location. I happen to be on Windows 7 x64 bit.

1
2
[core]
    editor = "/C/Program Files (x86)/Notepad++/notepad++.exe" -m

Google Trend of Subversion vs. Git

Interesting to see the trend of using Git keeps increasing.  It has been a battle within our company as to whether we will switch off ClearCase and pick Subversion or Git.  In my mind there is only one choice but it is not me that gets to decide 🙂

Google trend graph of Subversion vs. Git: http://bit.ly/g9Kf1Q

Client Side Git Hook

A client side Git hook that I wrote and are using at work. Thought others might have a similar need. Basically it will check the selenium file for the owners and see if our group is in that ownership. If the file is not in our group a message is displayed saying that the owner will need to get permissions and code review by the owners.

Of course you can use any language you want to execute your client side git hook. I thought shell scripting would just be easiest in my case since it wasn’t going to be that much code and anyone that has git will either be running in windows with cygwin and thus of bash or they will be in Linux.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#!/bin/bash
#
# This hook is meant to do a pre-check to see if we have
# files outside of common components that need dac
# permissions
#
# Contact: Ryan Alberts
#
#############################################################

#Get the modified files
files_modified=`git diff --cached --name-only`

#echo "The present working directory is `pwd`"

#false or 0 if we do not need dac permissions
need_dac=0

#Commit message
commit_msg=`cat $1`

if [[ $commit_msg == *DAC* ]]
then
    exit 0
fi

#Go through the files in the submission
for file in ${files_modified[@]}
do
    accepted_path=0
   
    check=`grep -s wc-caIntegSprintTester $file`
   
    #Check if it is apart of our package
    if [[ $check == *wc-caIntegSprintTester* ]]
    then
        accepted_path=1
    fi

    if [ $accepted_path -eq 0 ]
    then
        echo "File is owned by another team, and may require DAC permissions!"
        echo "  File: $file"
        need_dac=1
    fi
   
done

#Exit Code For Commit Message Warning Or Not
if [ "$need_dac" -eq "1" ]
then
    echo ""
    echo ">>> Notice <<<"
    echo "Please contact the branch master and work on requesting DAC permissions for the files listed above."
    echo "You can avoid seeing this message by adding 'DAC' anywhere within the commit message."
    echo ""

    exit 1
fi

#Everything looks good - allow them to commit.
exit 0

Gerrit Workflow

The workflow defines a process for using with Google’s Gerrit project. It is excellent in a number of ways! If you are using Git at your company and want to have a nice code review process as well as a way to verify and have a few more checks and balances, this is an amazing tool that Google has provided open source. I did make a few customizations to the tool in order to better suite our needs within the company and maybe I will share those once I get some more free time.

The idea with the following workflow is to show you a developer process from beginning to the end of a feature using Gerrit.  We are not using Repo which is a Google developed tool to work with Git and Gerrit.  We are using straight out of the box Git with Gerrit.  In our company we have a few proprietary development build processes but I try to call those out in the workflow so that you can tell how it could be adapted to your company or open source project.

Workflow

  • Implement feature
  • 1
    2
     //Create topic branch off of master
    git checkout -b topic origin/master
  • Commit changes. Commit as many times as you want to the topic branch.
  • Get latest code frequently and especially before you push.
  • 1
    git pull
  • Fix Merge Conflicts
  • 1
    2
    3
     git mergetool
    //'''Do *NOT*''' commit after you do the merge
    git rebase --continue
  • Compile the code
  • 1
    2
    3
    4
    //This is an internal shortcut for us to do a full compile just like the integration hudson builds
    //You really want to be able to replicate exactly what the integration machines are doing and
    //make it as easy as possible.
    projbuild
  • Validate the code (This means running your unit tests, integration tests, a subset of all the selenium tests, etc.)
  • 1
    projbuild dev_check
  • Prepare a single commit for code review by squashing your commits
  • Create another local branch
  • 1
    git checkout -b topicForCodeReview origin/master
  • Merge squash your topic branch into your topicForCodeReview branch
  • 1
    git merge --squash topic
  • The squash leaves the changes in your topicForCodeReview branch in the staged state. You’ll need to fire up git gui and commit them to that branch.
  • Push for code review
  • 1
    git push for-code-review
  • Fix any merge issues using git mergetool if necessary.
  • Note: If you choose not to squash before pushing for code review, every commit will get a separate code review!! This is not recommended.

Setup

You will need to setup the git config a certain way in order to be able to pull off this workflow.  Pretty trivial changes though, so don’t worry to much yet 🙂

  • Set rebase to always
  • 1
    2
    [core]
      rebase = always
  • Set up the shortcut for “for-code-review”
  • 1
    2
    3
    [remote "for-code-review"]
      url = <main git uploading repository location>
      push = HEAD:refs/for/master

Git Workflow – In Response

Just wanted to share the following with others since it is in response to a yammer post within my organization.  Maybe it will be slightly helpful to others.  I do realize I am leaving a large part of the thread out of this.  Hopefully I will be able to come back later and actually post our Git workflow.

———–

Git does allow a lot of flexibility in setting up a workflow. It is essential to understand the workflow possibilities and tweak that to fit the organization. Steven has a good point that it is possible to push such that you re-write history. While this is allowed, it can easily be turned off and set by access permissions and/or server side hooks. This is controlled and managed using Gerrit for our team. That way only a limited number of people have the ability to force change history.

There was mention of using “rebase” to change the workflow. From my experience, this has improved the workflow in Git. Our team has “rebase = always” setup so that anyone making a branch will automatically get it setup to be rebased onto the latest code. When anyone sets up a Git repo they run a small setup script that does the aforementioned and some additional tweaks for our workflow. A benefit that you get with using rebase is that your git history is much easier to read since you are really committing only fast-forward changes (less actual merge commits – kind of to John’s point). Since we push everything through Gerrit, developers have the opportunity to do a code review, check their changes, and copy anyone on the change *before* it gets committed to the active development stream.

Redmine with GIT Repository Setup on Ubuntu

This is a few pointers on setting up redmine having git as a repository hooked up to it.  This also takes into account using gitosis for authentication.

Installed under:
/opt/redmine
Forwarding from Apache to the Webbrick server
<VirtualHost *:80>
Servername timetrack.ryanalberts.com
ProxyPass / http://127.0.0.1:3001/
ProxyPassReverse / http://127.0.0.1:3001/
</VirtualHost>
Had to add the exact IP for redmine in the proxy pass for security reasons:
/etc/apache2/sites-enabled$ sudo vi ../mods-enabled/proxy.conf