alexcuesta

My tech blog

Using Git and Subversion

leave a comment »

After reading Richard Paul’s about using git on a subversion repository, I always wanted to give it a try. I don’t regret so far. Git handles branches and merging very well and I haven’t seen any weird thing such “obstruction” or “tree conflicts”.

This is my recipe to use git on a subversion repository from bash, also inspired on this very good article “Effectively using Git with Subversion” and completed by reading a lot.

How to use git on subversion

1.- Clone Subversion repository on your local computer using git

Git is a distributed version control system. Distributed means that every machine has a copy of the repository. In order to use Git on a Subversion repository you need to clone the svn repository on your machine: trunk, branches and tags.

git-svn clone -s http://example.com/my_subversion_repo local_dir

Notice that you should point to the root of the subversion repository, not to trunk. This was one of my problems in the begining.

The option -s means “I have the standard svn layout”, trunk, branches and tags.

You might want to add your svn ignore files:

git-svn show-ignore > .gitignore

2.- Create a story branch and use it

Once you have your git repository cloned from subversion you can start working. I normally create a “story branch” like this:

git checkout -b story_branch

You can see git branches using this command:

git branch

Or all git and subversion branches:

git branch -a

If you only want to work on a svn branch, just checkout the remote branch like this:

git checkout remote/svnbranch

This does not mean you are working on the remote repo, you are still working on your local copy. Once you finish your work, you have to send your changes to subversion. Keep reading.

3.- Staging and committing changes

Before committing your changes you need to “stage” them. Git has an intermediate area called “stage” and only commits files stored in the stage. Think about it as a mail outbox.

Before staging files you might need to know which ones have been changed. This command will tell you which files have been changed or created but untracked:

git status

In order to “stage” the files you want to commit, run this command:

git add path/to/file

If you just want to stage all modified files (but not deleted) just run:

git add .

Adds all files (changed and removed)

git add -u .

Run git status again to verify that all the files you want to commit are in the stage area and then commit:

git commit

This will start your editor (vi for example) so you can enter a commit message. Remember that a good commit message should have:

  • A title summarizing what’s been done, ideally containing the issue number from your project tracking application (Jira for example)
  • A blank line
  • A thorough description if necessary

If you want to skip the editor just run:

git commit -m "message"

4.- Get other developer changes into your branch (update)

Many times, other developers commit changes before you finish your task. If you want to incorporate other developers changes, first commit your changes, then rebase:

git svn rebase

This command is awesome! It just merges down changes from the original branch into your local branch. In other words, if someone modifies the remote ‘subversion trunk’ and your ‘git story branch’ was forked from your ‘git master branch’ (which is a copy of trunk), git will fetch those changes from svn trunk and will merge them into your ‘git story branch’. The documentation explains this command very well.

Updating without having to commit

Sometimes it isn’t reasonable since your changes are not yet ready to be committed (you haven’t finished/tested/improved your work). But don’t worry, git has a native solution also for this problem, just follow these steps:

  • put aside your changes using the command: git-stash
  • update your working copy using: git-svn rebase as usual
  • take back your changes typing: git-stash apply
  • clear “the stash” typing: git-stash clear

5.- Reverting uncommitted changes

In git this is called “reset”.

git reset --hard HEAD

I don’t understand completely how this command works yet but as far as I understand it moves the index of changes to the previous state.

6.- Reverting committed changes

git revert HEAD

This will create a new commit which undoes the change in HEAD

7.- Merging branch

Once you finish your task on your local ‘story branch’, you’ll probably want to merge it up into ‘master’. Change to the branch master first:

git checkout master

Rebase possible changes made on subversion trunk:

git svn rebase

Merge:

git merge story_branch

This will try to run a “fast forward” merge by default, in other words, it will incorporate each commit on the ‘story branch’ and master will look as if no branch had existed before. I don’t like this because if you want to check the history you don’t have a way of knowing in which the branch was merged down into master.

My preferred option is “no fast forward”:

git merge --no-ff -m "commit message"

This does exactly the same as fast forward but it also generates an empty commit message so you can see in which commit the branch was merged. Besides, when you send your changes to svn you will see only one commit which looks very clean.

8.- Solving conflicts

This is just a question of editing the conflict, add it to the stage area and commit.

I usually edit changes  with a normal editor or with the plugin JGit/EGit for Eclipse. There is a built-in tool on git called “git-mergetool” but I’ve never used it.

9.- Send your changes to subversion

git svn dcommit

10.- Amending commit messages

I had problems sending my changes to svn the first time because we are using pre-commit hooks and I forgot to include my issue number in the commit message. In order to modify commit messages, first I need to know the commit hash id:

git log

And then I run the following command:

git rebase --interactive $parent_of_flawed_commit

Be aware you have to use the commit parent hash id.

An editor will come up, with a list of all commits since the one you gave.

  • Change pick to reword (or on old versions of Git, to edit) in front of any commits you want to fix.
  • Once you save, git will replay the listed commits.

Git will drop back you into your editor for every commit you said you want to reword, and into the shell for every commit you wanted to edit. If you’re in the shell:

  • Change the commit in any way you like.
  • git commit –amend
  • git rebase –continue

11.- Get new branches from subversion

If you need to update your cloned version of subversion repository, just run:

git svn fetch

Final step: convince all your colleagues to use git and move to it!😉

Written by alexcuesta

June 18, 2011 at 11:16 am

Posted in Git/Svn

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: