Created
January 7, 2009 02:20
-
-
Save stepheneb/44147 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Hi Brent, | |
Here's a special intro to git for you (and anybody else on ruby-core | |
interested in your patches). | |
I'm not writing any kind of complete introduction -- I'm writing just enough | |
so you can do several things which should be interesting to you. I'm definitely | |
NOT presenting enough info so you can't easily mess things up. | |
The idea is to quickly get to some use of git that provides real value ... so | |
it becomes actually worth it to you to learn it. | |
So here's what's covered: | |
1. Get git installed from source using git (so you can update it easily later). | |
2. Cloning an existing subversion repository so you can easily keep | |
up-to-date with another project and view the changesets. | |
3. Clone MRI Ruby, apply your MBARI memory patches in a new branch, and push | |
that branch to a public git repo so others can more easily try the patches. | |
fyi: In my examples below I create directories with suffixes | |
that indicate to me what kind of repository they hold -- | |
dir.git for a dir that has a git repo and dir.svn.git for a | |
dir that has a git repo cloned from a svn repo. Nobody else | |
I know does this -- you don't need to do this -- it's just | |
a convention I use. | |
----------------------------------------------------------------------- | |
1. Get git installed from source using git (so you can update it easily later). | |
There are other ways of getting git but building it from source is so easy. | |
Get the tar.gz archive. | |
Starting from the download link on his page: http://git-scm.com/download | |
$ wget http://kernel.org/pub/software/scm/git/git-1.6.1.tar.gz | |
$ tar xzf git-1.6.1.tar.gz | |
$ cd git-1.6.1 | |
$ make | |
$ make install | |
$ cd .. | |
That will install git in your ~/bin dir. | |
Put ~/bin on your path and now use git to clone git: | |
$ git clone git://git.kernel.org/pub/scm/git/git.git git.git | |
$ cd git.git | |
Install the bash completion scripts: | |
Follow the instructions at the beginning of this file: | |
contrib/completion/git-completion.bash | |
to install the bash completion scripts. | |
I'm assuming you use bash -- if not look in this dir: | |
contrib/completion/ | |
to see if there are completion scripts for the shell you use. | |
Now your shell prompt should look something like this, | |
the branch you are on is displayed in your prompt: | |
[git.git (master)]$ | |
Compile and install a new git from the git clone | |
Right now you have the master branch checked out in your working dir. | |
The whole repo you cloned is in this dir: | |
git.git/.git | |
[yeah ... I know .. that's a case where my directory suffix conventions look insane] | |
Unless you want the bleeding edge git instead checkout the most | |
recent stable tagged version -- list the tags in your local repo: | |
[git.git (master)]$ git tag | |
Looks like v1.6.1 is the latest stable tag so create a new local | |
branch and check it out into your working dir | |
[git.git (master)]$ git checkout -b v1.6.1 | |
Switched to a new branch "v1.6.1" | |
[git.git (v1.6.1)]$ | |
Now make and install that version -- it's probably | |
the same as the one you just downloaded | |
[git.git (v1.6.1)]$ make | |
[git.git (v1.6.1)]$ make install | |
Now you can delete the original tar archive. | |
If a new stable (or unstable) branch of git appears you want to use | |
just update your local cloned repository. | |
[git.git (v1.6.1)]$ git fetch | |
That changes nothing in your working directory -- but let's say there's | |
now a stable 1.6.2 release -- your git fetch operation copied that new | |
objects that make up that branch into your local repository. You just need | |
to make a new local branch and check it out into your working directory. | |
[git.git (v1.6.1)]$ git checkout -b v1.6.2 | |
Switched to a new branch "v1.6.2" | |
[git.git (v1.6.2)]$ make | |
[git.git (v1.6.2)]$ make install | |
# start the TCL X11 git visualization tool gitk | |
gitk& | |
You can view all the changesets for git in gitk | |
----------------------------------------------------------------------- | |
2. Cloning an existing subversion repository so you can easily keep up-to-date | |
with another project and view the changesets. | |
I'm still assuming here you are not making commits or patches to this project so | |
I haven't yet described how to setup your general git configuraion ... | |
Let's say you just want to be able to easily keep up-to-date with ruby-debug | |
and be able to review their changesets. Ruby debug is hosted in a svn repo here: | |
http://ruby-debug.rubyforge.org/svn | |
Opening that page shows that it has a common form for svn repos of branches, | |
tags, and trunk (I'm going to ignore the branch named ruby-debug-0.10.3). | |
Clone a copy of the trunk, branches, and tags directories in the svn repo: | |
$ git svn clone --stdlayout http://ruby-debug.rubyforge.org/svn ruby-debug.svn.git | |
This will download all 905 revisions in the svn repo that occur in the trunk, | |
branches, and tags directories. It took about 10m for me. | |
Once you have your own git clone of the ruby-debug svn repo updates will be | |
very fast. | |
$ cd [ruby-debug.svn.git | |
[ruby-debug.svn.git (master)]$ git svn rebase | |
Current branch master is up to date. | |
----------------------------------------------------------------------- | |
3. Clone MRI Ruby, apply your MBARI memory patches in a new branch, and push | |
that branch to a public git repo so others can more easily try the patches. | |
If you were a committer to Ruby and wanted to use Git you'd clone the Ruby svn repo -- | |
but that would take a very long time and because you are just making matches and new | |
branches you'd like people to try there is an easier way. | |
Once an hour Vladimir Sizikov" <vsizikov@gmail.com> (vvs) pushes any new | |
revisions to the Ruby svn repo to a public git clone on github: | |
http://github.com/rubyspec/matzruby/tree/master | |
Initially importing a large svn repo into git takes a long time but this repo is | |
now in native git form so it's much faster to get it: | |
$ git clone git://github.com/rubyspec/matzruby.git matzruby.git | |
$ cd matzruby.git | |
Cloning the entire Matz Ruby git repo took 36m on my DSL connection. The | |
total size of the content in dir that holds the whole repo: | |
matzruby.git/.git is just 73M. This 73M holds all the branches, tags, and | |
revisions for Ruby. | |
OK -- now for some more advanced stuff -- let's checkout Ruby v1.8.7 | |
patchlevel 72 into a new branch named v1_8_7_72_mbari, apply your | |
patches in a series of commits, fork the matzruby repo on github and | |
push your new branch to your fork of the matzruby repo. | |
This is where it gets both more tricky (easier to shoot yourself) but even | |
more useful. | |
First checkout a the tag v1_8_7_72 into your local branch. In subversion | |
a tag is just a convention -- it's really a branch -- but in git a tag | |
is just a useful label referencing a specific commit instance. I know that | |
won't make much sense yet. But here's what it looks like when you checkout | |
a tag in git: | |
[matzruby.git (master)]$ git checkout v1_8_7_72 | |
Checking out files: 100% (2560/2560), done. | |
Note: moving to "v1_8_7_72" which isn't a local branch | |
If you want to create a new branch from this checkout, you may do so | |
(now or later) by using -b with the checkout command again. Example: | |
git checkout -b <new_branch_name> | |
HEAD is now at 0ca4925... add tag v1_8_7_72 | |
Git warn's you that you haven't actually made a new branch yet -- you've | |
just changed the state of your working directory to the commit tree | |
associated with the tag: v1_8_7_72. | |
Now make a new branch named v1_8_7_72_mbari -- it will automatically be | |
associated with the commit tree associated with the tag you just checked | |
out: | |
[matzruby.git (0ca4925...)]$ git checkout -b v1_8_7_72_mbari | |
Switched to a new branch "v1_8_7_72_mbari" | |
[matzruby.git (v1_8_7_72_mbari)]$ | |
I downloaded your directory of patches to my matzruby dir and tried to apply | |
them but the application process failed because your patches expect svn | |
variables like this: | |
$Author:$ | |
To actually look like this: | |
$Author: shyouhei $ | |
Here's what it looked like: | |
[matzruby.git (v1_8_7_72_mbari)]$ MBARIp72patches/apply . | |
Applying all patches in MBARIp72patches to . | |
Applying MBARIp72patches/ruby-1.8.7-p72-mbari1.patch: | |
patching file ChangeLog | |
patching file eval.c | |
Hunk #1 FAILED at 2. | |
1 out of 31 hunks FAILED -- saving rejects to file eval.c.rej | |
patching file version.h | |
Great -- I've gotten half way through a set of patches and now I've | |
got a mess to clean up somehow. ... | |
I'm sure there was a better way but I just deleted all these specific | |
patches from your set and cleaned up my working directory by doing | |
a hard reset back to the state of the last commit (git calls this HEAD). | |
[matzruby.git (v1_8_7_72_mbari)]$ git reset HEAD --hard | |
HEAD is now at 0ca4925 add tag v1_8_7_72 | |
Well I intended to but several times I tried and found more errors -- | |
they were all the same kind -- not errors I actually had to think about | |
to fix -- I just need to more effectively find all the patch hunks that | |
had to be deleted. | |
After I got all the patches to apply cleanly I erased them one more time: | |
[matzruby.git (v1_8_7_72_mbari)]$ git reset HEAD --hard | |
HEAD is now at 0ca4925 add tag v1_8_7_72 | |
Running git log will show one screenful of the most recent commits: | |
[matzruby.git (v1_8_7_72_mbari)]$ git log | |
commit 0ca4925414627223b1f7a507b0f31775501a5685 | |
Author: shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | |
Date: Mon Aug 11 00:37:26 2008 +0000 | |
add tag v1_8_7_72 | |
git-svn-id: http://svn.ruby-lang.org/repos/ruby/tags/v1_8_7_72@18480 b2dd03c8-39d4-4d8f-98ff-823fe69b080e | |
OK -- that looks right -- right now the HEAD of the v1_8_7_72_mbari branch | |
is pointing to the commit tree where the svn tag v1_8_7_72 was added. | |
FYI: lines like these in the git log messages: | |
git-svn-id: http://svn.ruby-lang.org/repos/ruby/tags/v1_8_7_72@18480 b2dd03c8-39d4-4d8f-98ff-823fe69b080e | |
are automatically added to the git log of commits when the git svn import occurs. | |
I then created and ran this short ruby script to commit each one of your patches as | |
a separate commit: | |
[matzruby.git (v1_8_7_72_mbari)]$ cat commit_mbari_patches.rb | |
patches = Dir["MBARIp72patches/ruby-1.8.7-p72-mbari*"] | |
patches.each do |p| | |
`patch -p1 < #{p}` | |
`git commit -a -m "#{File.basename(p)}"` | |
end | |
[matzruby.git (v1_8_7_72_mbari)]$ ruby commit_mbari_patches.rb | |
Now checking the log shows my commits of your patches: | |
[matzruby.git (v1_8_7_72_mbari)]$ git log | |
commit 7e58194806ab779c4b9a2c77acda693727ecc60f | |
Author: Stephen Bannasch <stephen.bannasch@gmail.com> | |
Date: Tue Jan 6 17:53:23 2009 -0500 | |
ruby-1.8.7-p72-mbari7.patch | |
commit 8a4e26f24a39d9d538999111281acc5c55d1aff2 | |
Author: Stephen Bannasch <stephen.bannasch@gmail.com> | |
Date: Tue Jan 6 17:53:23 2009 -0500 | |
ruby-1.8.7-p72-mbari6.patch | |
etc ... | |
I already have an account on github: | |
http://github.com/stepheneb | |
so I logged in to my account and opened the matzruby repo page: | |
http://github.com/rubyspec/matzruby/tree/master | |
and clicked the fork button. That took github about 1m and after I refreshed | |
my new repo page: | |
http://github.com/stepheneb/matzruby/tree/master | |
I had a fork of matzruby! | |
Back in my local repo I had one remote reference to the original matzruby repo | |
on github: | |
$ git remote -v | |
origin git://github.com/rubyspec/matzruby.git | |
I added another to the private clone url to my github fork and labeled | |
it 'stepheneb': | |
[matzruby.git (v1_8_7_72_mbari)]$ git remote add stepheneb git@github.com:stepheneb/matzruby.git | |
Now listing the remotes shows two separate repositories I can reference: | |
[matzruby.git (v1_8_7_72_mbari)]$ git remote -v | |
origin git://github.com/rubyspec/matzruby.git | |
stepheneb git@github.com:stepheneb/matzruby.git | |
Note the different form of the remote url. Mine uses an ssh | |
connection so I can push to it. | |
I then pushed my local v1_8_7_72_mbari branch to my remote fork | |
of matzruby using the remote named: stepheneb | |
[matzruby.git (v1_8_7_72_mbari)]$ git push stepheneb v1_8_7_72_mbari | |
Counting objects: 54, done. | |
Compressing objects: 100% (44/44), done. | |
Writing objects: 100% (44/44), 20.66 KiB, done. | |
Total 44 (delta 36), reused 0 (delta 0) | |
To git@github.com:stepheneb/matzruby.git | |
* [new branch] v1_8_7_72_mbari -> v1_8_7_72_mbari | |
Now if you open my matzruby fork in your browser: | |
http://github.com/stepheneb/matzruby/tree | |
and select 'all branches' you'll see v1_8_7_72_mbari listed. | |
I can recreate your patch set locally like this: | |
$ git format-patch v1_8_7_72 | |
0001-ruby-1.8.7-p72-mbari1.patch.patch | |
0002-ruby-1.8.7-p72-mbari2.patch.patch | |
0003-ruby-1.8.7-p72-mbari3.patch.patch | |
0004-ruby-1.8.7-p72-mbari4.patch.patch | |
0005-ruby-1.8.7-p72-mbari5.patch.patch | |
0006-ruby-1.8.7-p72-mbari6.patch.patch | |
0007-ruby-1.8.7-p72-mbari7.patch.patch | |
That created seven patch files, one for each commit I made (minus | |
the elements I deleted manually). | |
The names look silly because I didn't truncate the string '.patch' | |
from my commit log message but each one of them can be applied to | |
a svn repo checkout of 1.8.7 patchlevel 72 using the standard patch | |
command. | |
I could post these patches for you to download or you can git clone | |
the matzruby repo yourself, add my repo as a remote and get a copy | |
of my v1_8_7_72_mbari branch to start working on like his: | |
$ git clone git://github.com/rubyspec/matzruby.git matzruby.git | |
$ cd matzruby.git | |
[matzruby.git (master)]$ git remote add stephens-fork git://github.com/stepheneb/matzruby.git | |
[matzruby.git (master)]$ git fetch stephens-fork | |
[matzruby.git (master)]$ git checkout -b stephens-mbari stephens-fork/v1_8_7_72_mbari | |
Now you have checked out in your local working directory my v1_8_7_72_mbari | |
branch. In your local git repo you now have a branch named: stephens-mbari | |
[matzruby.git (stephens-mbari)]$ git branch | |
master | |
* stephens-mbari | |
If it is worth continuing from there you can merge the changes in my mbari branch | |
to a new development branch you make named mbari: | |
[matzruby.git (stephens-mbari)]$ git checkout -b mbari | |
Now delete my branch: | |
[matzruby.git (mbari)]$ git branch -d stephens-mbari | |
And continue work on your branch ... | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment