I am involved in a number of projects where we use different open source projects, but for some reason, we always seem to be operating on the very edge of what these projects can actually support. Most of the time, we do not have commit access, but we're usually more than willing to contribute patches. Because we cannot commit directly, we have to track our changes elsewhere (and some changes are not even relevant to the original project, so they should just live in our own system).
I've tried to use Subversion for this earlier - the Subversion book talks about how to do vendor branches. However, it has never been quite the success I wanted, somehow it was just too much trouble. Lately, however, I've found git to be a much better solution, because git can also be used for tracking Subversion repositories, and at the same time you get to commit changes to your local repository.
Generally, it goes like this:
-
git svn clone http://hudson-eclipse.googlecode.com/svn/trunk hudson-eclipse
-
cd hudson-eclipse
-
... make changes ...
-
git add changed/file
-
git commit -m 'fixed bug #34'
Creating a patch with the last change is simple:
-
git format-patch -1
This will create a file named 0001-first-line-of-commit-message, and this can then be sent upstream.
At some point, the local repository can be synced with the SVN repository by running
-
git svn rebase
This command requires that no local changes are uncommitted. If you have something which has been changed, but should not be committed, you can stash it using
-
git stash
After syncing, retrieve the changes again with
-
git stash apply
Sometimes, conflicts occur when running svn rebase. When they do, don't panic. If everything goes wrong, just run
-
git rebase --abort
This will roll everything back to the state it was in before you started the rebase. However, you should be able to resolve the conflicts. See "git status" to check which files have conflicts. Resolve the conflicts manually, then git add each of the files. Finally, to resume rebasing, execute
-
git rebase --continue
Usually, I also mirror my local repository to a public repository such as Gitorious, just to be sure everybody else can reach my changes. This will also make sure that there is always a backup of the repository.
The first time, push everything like this:
-
git push --all git@gitorious.org:project/mainline.git
After that, just run this each time changes should be published:
-
git push
Others can then do the usual git stuff to clone your repository:
-
git pull git@gitorious.org:project/mainline.git
Finally, I recommend using "git gui" for managing commits. Using the gui, it is much easier to add separate changes in the same file to different commits. Of course, this shouldn't be necessary, but if you're anything like me, you sometimes forget to commit before starting on a new task.



