Lately I have been reading about and toying with Git a lot — and I’m truly fascinated! (In fact, I’m even using it to track the progress of this very posting.)
However, I’m not primarily interested in the distributed part. More important, to me, is the fact that Git gives me a private revision history (local commits). That way I can commit frequently without having to worry about publishing my changes prematurely.[1]
Since for TiddlyWiki we’re using Subversion, I’ve started looking into Git’s SVN module. With this I can use Git locally while still interacting with the public Subversion repository.
The following guide is to serve as a quick introduction to Git-SVN, hopefully making it easy for others (e.g. fellow Osmosoftonians) to get started.
Note that I’m an enthusiastic command-line user, which is why this guide does not cover any GUIs. Also, I’m far from being a Git expert at this point, so feel free to suggest improvements!
Initial Setup
-
check out Subversion repository:[2][3]
git svn clone -T[trunk_subdir] -t[tags_subdir] -b[branches_subdir] [URL]
(e.g.
git svn clone -TTrunk -tTags -bBranches http://svn.tiddlywiki.org)
N.B.: For TiddlyWiki, it might not be desirable to convert the Trunk, Tags and Branches directories to metadata, as this might interfere with Cook. -
create branch for work in progress (WIP):
git checkout -b [branch]
Working with Git
-
modify files on WIP branch, creating (and amending) local commits:[4]
git add [files] git commit -m "[message]" git commit --amend
-
switch to master branch:
git checkout master
-
grab changes from WIP branch:[5]
git merge --squash [branch]
-
commit changes and push to Subversion:[6]
git commit -a -m "[message]" git svn dcommit
-
switch back to WIP branch:[7]
git checkout [branch] git reset --hard master
(if there are additional commits on the branch,
git rebase mastershould be used — which might lead to merge conflicts though)
Useful Commands
- git branch (list, create or delete branches)
- git diff [-w] [--color-words] (display changes)
- git apply (patching)
- git status (working tree status)
- git log (commit history)[8]
- git reflog (comprehensive history)
- git svn rebase (update local repository)
- git checkout [files] (revert changes)
- git config (user preferences)[9]
- git gui (graphical user interface)
- gitk (repository browser)
Thanks to Kerry for getting me started with Git in the first place!
2008-09-30: minor updates (removed hyphens from git svn commands, updated .gitconfig, note on converting metadata on checkout)
2008-11-03: changed final git merge master to git reset --hard master (includes a note on git rebase master, as recommended by Kerry)
- The same is true for other DVCS, like Mercurial — though I have only worked with Git so far. [↩]
- Cloning an entire Subversion repository can take a while (mostly due to protocol overhead) — an alternative is to grab only the latest revision:
git svn init [URL]; git svn fetch -r HEAD. [↩] - Instead of manually specifying directory names for trunk, tags and branches,
-scan be used for the standard naming convention “trunk”, “tags” and “branches”. [↩] - Use
git commit -a -m "[message]"to automatically add all modified files. [↩] - Squashing means that several local commits can be merged into a single commit. [↩]
dcommitwill automatically perform an update (rebase). [↩]- The merge operation is required due to the rewritten commit history on the master. [↩]
git logcan be used to display the differences between two branches:git log <a>..<b>— for example:git log origin/master..master(Git repositories),git log remotes/trunk..master(SVN repositories) [↩]- My current
.gitconfigfile (latest version on GitHub):[user] name = FND [alias] ci = commit cia = commit -a cim = commit -m ciam = commit -a -m co = checkout diffi = diff -M --color-words diffw = diff -M -w diffx = diff -M -w --color-words merges = merge --squash [color] branch = auto diff = auto status = auto [color "branch"] current = yellow reverse local = yellow remote = green [color "diff"] plain = white meta = yellow bold frag = magenta bold old = red bold new = green bold [color "status"] header = white added = yellow changed = green untracked = cyan [svn] rmdir = true
[↩]