Janson and I have been using Git for a few months now at work. We’re still keeping an open mind with regards to Mercurial and Bazaar however its clear that we’ll be moving to a distributed version control.
Working with git, I’ve come across a few gotchas and a few takeaways, especially in regards to git-svn.
Here’s some layman’s definitions to two very common terms with git. These are actually a very narrow view of what they actually do, but helps when starting out.
- “rebase” typically means to take the changes from a source branch, and bring them into the branch you are currently working with
- “merge” typically means to take the changes in your current branch, and push them into another branch
Ignore files and svn:ignore
There’s two ways for git to track ignored files. You can track it for your branch only in
DIR/.git/info/exclude as well as a shared revisioned file at
DIR/.gitignore. We’ve been preferring the latter on most of our projects.
When using git-svn, you can have it dump all svn:ignores into a git file which is convienient, however I ran into a few issues where git was trying to add / remove files that svn thought were ignored. If you’re going to interface with svn, I’d recommend keeping all ignores at the git level.
One thing thats cool about git is the amount of docs out there. That being said, it was hard for me to get the hang of merging conflicts. Its actually a relatively easy process once you’ve done it a few times. More often than not, the conflicts will happen on a rebase.
- First edit the conflicted file and merge the changes by hand
- Run a
git add path/to/file
- Tell git to finish the rebase by
git rebase --continue
Don’t under any circumstances delete the
.dotest folder. I repeat, leave that folder alone. I think there’s some carry over from using svn that some people think that how you finish the merge. I was one of those people, and I know a few people who did the same. The
.dotest allows you to run
git rebase --abort to quit a rebase in the middle of a conflict.
Most people come across this within the first few days of using git. Unlike svn, you have to tell git what files you want to commit every changeset. You do this by running
git add path/to/file on already revisioned files. However to save the hassle you can run
git commit -a to add any tracked files to the next commit.
On a related note, you can use wildcards with
git add. So
git add * will add all the untracked files in the directory and any subdirectories. That can be helpful at times.
This one seemed a bit unintuitive to me. Lets say you have a file, made some changes, then wanted to dump all changes for the latest known revision. To do this you run
git checkout path/to/file or
git checkout . to dump your entire changeset.
git reset unless you really know what you are doing. When using git-svn, this can revert all changes since your last rebase with svn. Which can be a real pain in the ass.
Showing old revisions
You can do this pretty easily by running
git log path/to/file taking the commit id and then running
git show commit-id:path/to/file.
Dumping changes in order to rebase with svn
This can be a pain, and if anyone has an easier solution, please share. Let’s say you have a repository that has recently been rebased against svn. You start making some changes, and then you realize someone else commited something to svn that you need. The approach I’ve been taking is this:
- First make a patch of you current changes
git diff > changes.patch
- Reset all your changes
git checkout .
- Rebase with svn
- Re-apply the changes to your directory.
I hope this helps. If you have any other suggestions or tips, by all means share them.