|Line 80:||Line 80:|
= howto's =
= howto's =
=== How to use git branches with git svn ===
=== How to use git branches with git svn ===
Revision as of 14:10, 26 December 2012
This tutorial collects information for users of git as subversion client, using git-svn. Please consider reading GitSvnCrashCourse, and the git-svn cheatsheet. As Git is distributed, commits (aka change sets) are referenced by hashes instead of svn's serial version numbers. Git tracks contents, not files or directories. Consider to use a real svn client to rename directories, as git-svn produces a lot of renames in svn, instead of one like the original. git-svn is not a good tool to convert from svn to git, see here for better options.
checkout / clone, log, configure basics
git svn clone -r 400:HEAD https://mysvnsrv.org/rep/trunk folder # choose a recent commit git log -5 git status git svn info git config --list
Create a .gitignore file on the toplevel to replicate svn's ignore properties.
echo "folder/or/file/to/ignore" > .gitignore
Make sure to remove directories from the svn tree if there are no files left in it. This is important for a directory move to have no left-overs:
git config --global svn.rmdir=true
commit to local Git
Git automatically tracks contents and therefor automatically detects all changes done with file browsers, programming tools etc.
git diff git add --all git diff --cached git commit -m "whatebber"
commit to remote SVN
To see what is going to be committed one can choose the following options.
gitk git-svn.. gitk git log remotes/git-svn.. --oneline git svn dcommit --dry-run
To really commit
git svn dcommit
Undo (backout, revert) changes and commits is done with standard git commands.
Things already committed to svn can be reverted:
git revert <hash> git svn dcommit
Things in the working tree can be reset (reverted) to what is checked in:
git reset --hard
Also, single files can be reset to a previous version. one caret means one version back:
git checkout HEAD^ -- singlefile git commit --amend
basic workflow, check out, fix, check in to svn
git svn clone -r 400:HEAD https://mysvnsrv.org/rep ... hack, hack, hack ... git add . git commit -m "qick fix" git dcommit
workflow with quickly setting away your main work and do a quick fix
git svn clone -r 400:HEAD https://mysvnsrv.org/rep git checkout -b bugfix-id-123 ... hack, hack, hack ... git stash "main work, save it for the moment" git stash list ... hack on quick fix ... git commit -m "qick fix" git dcommit git stash pop ... continue hack, hack, hack ...
workflow with local fix/feature branch
git svn clone https://mysvnsrv.org/rep git checkout -b bugfix-id-123 <hack, hack, hack> git add --all git commit -m "fixed issue 123" git checkout master git svn rebase git merge bugfix-id-123 git svn dcommit
How to use git branches with git svn
git-svn(1) allows you to use git as an interface to a Subversion repository. However, there are a number of caveats when doing this because Subversion's branching model is less powerful. git-merge(1) should not be used on the branch you intend to git svn dcommit from because the merge object cannot be expressed in a useful form to the Subversion repository when committing. This essentially makes it impossible to usefully use git branches for local development - yet the branching/merging mechanism is one of the most powerful features that git provides.
There are two ways to get around the git merge problem and so be able to use git branches for (local) development. For the following, assume you've branched and the commit genealogy looks like:
C--E--F branch / A--B--D master
The first merge solution is to replicate the changes you made on your branch to master using git-cherry-pick(1) (or alternatively git-format-patch(1) and git-am(1)). However, it can be rather laborious determining the list of required commits (C,E,F) and iteratively re-applying them to master (C', E', F').
C--E--F branch / A--B--D--C'--E'--F' master
Whilst this does allow you to develop multiple projects simultaneously and independently, this work-around isn't much friendlier than just working directly on master in the first place.
The second solution takes advantage of git-rebase(1) and git-branch(1). When you want to merge your changes back to master you rebase your branch with respect to master HEAD (i.e. what the Subversion repository looks like):
git checkout <branch> git rebase master
Your branch now looks like master plus the extra changes you made on the branch:
C"--E"--F" branch / A--B--D master
In fact, it's what you'd ideally like to git svn dcommit now (or later) but it's stuck on the wrong branch. So now we tell git that we'd like to pretend that the branching never happened and that branch is what master should really look like:
git branch -M master
The -M specifies that we want to do a forced rename of the branch (forced because master already exists):
Note that this destroys the development branch in the process* so this should only be done when you've finished development on the branch. However, there's nothing stopping you from re-branching again:
git checkout -b <branch>
o branch / A--B--D--C"--E"--F" master
- Technically we destroyed the old master branch but since branch can no longer be referred to by name it appears as though that is the object that was destroyed.
An Alternate Method Using `git-svn rebase`
If you have a branch like above, you can often perform a
git-svn rebase on the branch directly. Instead of rebasing to master, this rebases the branch directly onto the latest remote revision in subversion. Then you can
git-svn dcommit in the branch. Finally, check out
master and do another
git-svn rebase to bring it up to date. This will merge in the changes from the branch as well as any new changes in subversion. Note that with this method, the branch sticks around, but afterwards
gitk will show that it marks the same history as
master -- until you commit to it again or delete it, anyway.
- git-svn homepage: http://www.kernel.org/pub/software/scm/git/docs/git-svn.html
- Git cheat sheets: Zack Rusin's, in A4 by Jan Krüger, 2 sheets by Jan Krüger
- git-svn on en.wikibooks.org
- tcoffee description, including tagging, committing to a branch: http://code.google.com/p/tcoffee/wiki/SvnUsingGitClient
- An introduction to git-svn for Subversion/SVK users and deserters by Sam Vilain describes how to import from and work with Subversion repositories and SVK mirrors. Also describes why would one want to choose Git over Subversion.
- git(-svn) in 30 minutes on mikas blog, not only about git-svn.
- Using Git for Samba Development and Using Git-SVN for Samba4 Development