Skip to end of metadata
Go to start of metadata

Introduction

Git is a version control system designed for distributed development. As such, it provides a model that is more flexible than SVN in a number of ways. It can be used in concert with SVN with the git-svn command (which is actually a set of commands, depending on how you look at it). There is a trade off in complexity to be made if one uses Git with git-svn as opposed to using SVN directly. Accomplishing some tasks (particularly getting changes from your working branch w/ the method described below) are more complex to do. However, there are definite and pronounced benefits to using Git and git-svn, such as the ability to isolate changes for parallel features in their own branches.

Conceptual overview

Git uses a richer model than previous version control systems such as SVN, and because of that there is some learning that needs to take place to understand how to use Git. The most prominent difference is that a branch is a first class concept in Git that developers will use very regularly. The materials below give some recipes for certain tasks, but learning more about the concepts that Git uses is recommended. Here's one conceptual overview that looks decent: http://www.eecs.harvard.edu/~cduan/technical/git/.

Git and Eclipse

Git's integration with eclipse is needless to say less mature than SVNs, but it has progressed significantly and isn't too bad. You can get the plugin here: http://www.eclipse.org/egit/. If you decide to really embrace Git and git-svn for your work, I recommend you set up your Eclipse Quick Diff feature to use "A Git Revision" as your reference source (Window -> Preferences -> General -> Editors -> Text Editors -> Quick Diff).

Recipes:

Create and prepare your local repository

Create a directory for your local git repo (this will be your project directory in Eclipse)

Save yourself from accidentally committing project files

Add temporary ignores in the master branch (Note: this is not well tested). You don't want to have to redo your project file changes in each of your working branches, and you also don't want to accidentally commit changes to project files that are specific to you.

Create working branches

To isolate changes for different features or issues that you are working on, you want to create child branches off of the master that will each contain the related work. A good strategy is one branch per JIRA issue.

Commit back to SVN (in the safest way)

Note that this admittedly feels clunky, but it's worth taking these steps to avoid some annoying merge conflict / resolution scenarios.

Switching branches while you have uncommitted changes

method 1: the stash

Git has a special spot to squirrel away uncommitted files called the "stash". Note that the stash is global to all branches, so it can also be a handy way to move things from branch to branch.

method 2: a child branch

You can also squirrel away your changes in a child branch to your working branch.

Resolving merge conflicts

Occasionally you will have merge conflicts that Git can't resolve automatically. Here are a couple of links with pointers on how to deal with these situations:

Relocating the checked-out SVN repository

It is possible that the upstream Subversion repository location will change while you have a checked-out git-svn repo. If you are using Git as for local workflow only (not pushing commits to a shared Git repo), then it may be simpler to just re-clone/init from the new SVN url. However, if you have pushed Git commits remotely, it is possible to reconfigure your local Git repo for the new repository location (assuming the new location represents the same repository/UUID). Git-svn couples git commits to the origin SVN repository by embedding the original SVN url in the commit. Changing this url will change the Git commit SHA (basically rewrite all your history). Google results furnish various elaborate schemes for reconfiguring and patching up the Git repo, but the safest approach involves using built-in support for "rewriting" the Git-svn root url. This effectively tells Git to continue using the original SVN url for purposes of Git history, but use an independent URL (the new location) for actually retrieving and commit deltas (you will have to live with the old url in your commit history, but most likely you will be the only one that sees that).

See: http://www.spinics.net/lists/git/msg144510.html for discussion on this approach

Rough guideline:

Use the --dry-run flag liberally to ensure everything is sparkling clean before dcommit-ting any changes back upstream.

Working with multiple SVN branches

To limit the SVN branches that git-svn will check out, you can modify your .git/config file to specify explicit branch patterns.
E.g. to check out only the rice-2.1 and rice-2.1-kc branches, your branches variable for the svn remote definition may be defined as follows:

*

If you have not performed a full repository clone, or need to check out a branch which was created after your initial clone, you can simply edit the branches variable to include the new branch in the comma-separated list of branches:

I found I needed to re-specify the SVN revision range in order for git-svn to actually check out the new branch, e.g.:

...will cause some-new-branch to be fetched. It can then be checked out as normal:

You may have gotten in the habit of checking out your upstream branch to merge changes, so be sure to not accidentally check out the wrong branch when merging changes now that you have multiple upstream branches!

* an alternative is to specify multiple branches vars which will get merged, however I have not fully tested this:

    branches = branches/{rice-2.1}:refs/remotes/git-svn-branches/*
    branches = branches/{rice-2.1-kc}:refs/remotes/git-svn-branches/*

Bibliography

This information was gathered from a number of sources, including:

This wiki page his some similar info but with more specific use cases:

  • No labels