Fix make-array transforms.
[sbcl.git] / doc / GIT-FOR-SBCL-HACKERS.txt
index 693ec35..4440c42 100644 (file)
@@ -11,12 +11,12 @@ Make sure you have Git 1.5.something.
 When running on tty the commands pipe their output through less
 automatically, so you don't need to mentally add "| less" anywhere.
 
-Let's get started. First off, we need a gitified SBCL repository
-to clone. At the time of writing there are two Git mirrors for
-the CVS history:
+Let's get started. First off, we need a gitified SBCL repository to
+clone. At the time of writing there are two Git mirrors for the CVS
+history:
 
  git://sbcl.boinkor.net/sbcl.git
+
 and
 
  git://repo.or.cz/sbcl.git
@@ -30,7 +30,7 @@ The command
 
 clones the SBCL Git mirror into the directory sbcl-git (there's a
 naming convention in play here, but ignore that for now.) The clone
-contains full history, and is an independent repository on it's own
+contains full history, and is an independent repository on its own
 right. Doing the clone takes as long as downloading 25Mb takes on your
 line, but after that things are very fast.
 
@@ -40,7 +40,7 @@ snazzy a no-op pull is.
 
  git pull
 
-The directory .git inside the clone contains gits view of the
+The directory .git inside the clone contains Git's view of the
 repository -- no other Git files or directories are in the tree. Just
 for kicks:
 
@@ -72,8 +72,7 @@ in one step, which you will be doing a lot, since branches are really
 nice in Git! The magic is: "git checkout -b hack-a-bit-more" -- but
 leave that for another time.
 
-Let's do something. Edit version.lisp-expr, and maybe give SBCL some
-love.
+Let's do something. Edit BUGS, and maybe give SBCL some love.
 
  git diff                # shows you the changes in your tree
  git status              # shows you the state of files in the tree
@@ -85,7 +84,7 @@ nothing would happen. What's going on?
 Git has a notion of a separate "staging area", from which commits are
 made. You can add content to the it by using git-add:
 
- git add version.lisp-expr
+ git add BUGS
  git status
  git diff
 
@@ -93,13 +92,13 @@ Now git-status shows changes as part of a pending commit, but git-diff
 is silent!
 
 By default git-diff shows the differences between the working tree and
-the staging area (or the last commit if the staging area is empty.)
+the staging area (which starts out identical to HEAD after a checkout).
 
-Edit version.lisp-expr again. Now you have three versions of it
-(ignoring all the historical versions for a second) to compare:
+Edit BUGS again. Now you have three versions of it (ignoring all the
+historical versions for a second) to compare:
 
  git diff               # between tree and staging area
- git diff HEAD          # between tree last commit
+ git diff HEAD          # between tree and last commit
  git diff --cached      # between staging area and last commit
 
 If we were to do a git-commit now, it would commit the version in the
@@ -107,7 +106,7 @@ staging area, not the one in the tree.
 
 We like our latest version, so do
 
- git add version.lisp-expr
+ git add BUGS
 
 again. Now the latest version is in the staging area, and version that
 used to be there is gone. You don't need to worry about the staging
@@ -155,10 +154,10 @@ current version as a single diff. Similarly,
 
 can be used to compare two arbitrary versions. The -w switch tells Git
 to ignore whitespace changes -- you can usually leave it out, but it's
-nice when diffing across the great whilespacification patch.
+nice when diffing across the great whitespacification patches.
 
 Onwards: just so that we have a bit more history on the branch, edit
-version.lisp-expr again, and git-commit again. You can use
+BUGS again, and git-commit again. You can use
 
  git commit -a
 
@@ -179,17 +178,20 @@ full branch history merged. If there had been conflicts, the merge
 would not have been automatic, but you would have been called to
 resolve conflicts, etc.
 
-This is very nice for merging short-lived local branches, but not so
-good for merging things back onto master, or into "mainline" history:
+This is very nice for merging short-lived local branches, but not
+always so good for merging things back onto master, or into "mainline"
+history since you get all the commits that happened on the branch:
 
- * We don't want the version.lisp-expr from the branch, but a new one.
-   (Once we live in the brave new distributed world we may want to
-   rethink the version.lisp-expr a bit -- but that is neither here nor
-   now.)
+  "first cut at x"
+  "first cut at y"
+  "oops, x was wrong"
+  "implemented z"
+  "aargh, x was still wrong"
+  ...
 
- * When merging a long-lived branch with several small commits it
-   makes for a more readable history if we are able to merge it as a
-   few logical patches.
+When merging a branch like this, with oopses in the history, it is far
+better if we are able to merge it as a few logical patches -- the
+resulting history will be easier to understand.
 
 First option is to use --squash to squash all the commits into a
 single one.
@@ -197,9 +199,7 @@ single one.
  git checkout -b merge-experiment-2 master
  git merge --squash hack-a-bit
 
-This has the side-effect of not committing the changes immediately, so
-we can edit version.lisp-expr to taste, and commit changes (remeber to
-git-add the edited version.lisp-expr.)
+This has the side-effect of not committing the changes immediately.
 
 This is in effect similar to the usual way of merging back changes
 from a CVS branch: if we're told that the patch came from a branch, we
@@ -213,7 +213,8 @@ long-lived branches that are best merged in a few steps we can use
 
 to merge the changes upto a certain commit. Repeat a few times, and
 you have the whole branch merged. Other Git commands provide more
-advanced options. See eg. git-cherry-pick.
+advanced options. See eg. git-cherry-pick, which you will end up
+using sooner or later.
 
 Now, let's assume we have a private Git repository in ~/sbcl-git, and
 we want to publish it to the world. The easiest way is to fire up a
@@ -227,9 +228,9 @@ along the lines of "My private SBCL tree. Pulls from main sbcl.git
 repository, and trickles changes back to upstream CVS manually --
 from where they end up in sbcl.git. Turtles, you see." in the comment
 box. Then you will be directed to set up an account, which you will
-then have to add as a "pusher" to your SBCL fork. 
+then have to add as a "pusher" to your SBCL fork.
 
-Finally, add the following snipped (adjusting for your own name) in
+Finally, add the following snippet (adjusting for your own name) in
 ~/sbcl-git/.git/config
 
  [remote "public"]
@@ -249,17 +250,43 @@ and you can publish your own hacks on it via git-push.
 
 Since we're not (yet?) officially using Git, we want to get our
 changes back into the CVS. git-cvsexport is the perfect tool for this.
-This assumes that you have a developer CVS checkout in ~/sbcl-cvs, and
-wish to commit the changes you have wrought on branch foo-hacks
+
+First, to make things a bit easier, we add a command of our own to
+Git, by adding the following to ~/sbcl-git/.git/config:
+
+ [alias]
+        sbcl-export = cvsexportcommit -w /home/yourname/sbcl-cvs -v
+
+This assumes that you have a developer CVS checkout in ~/sbcl-cvs.
+
+To commit the the changes you have wrought on branch foo-hacks
 (compared to master):
 
+ # These three steps could be replaced by any other sequence that
+ # ends with all the changes you want to export to CVS at the top
+ # of the current branch (so that the final commit introduces all
+ # the changes.)
+ #
+ # In practice for small changes you may eg. just want to
+ #
+ #    git checkout -b wip-fix-bug-xxx master
+ #    ...fix bug on the branch...
+ #    git commit -a
+ #
  git checkout -b foo-hacks-to-cvs master
  git merge --squash foo-hacks
- edit version.lisp-expr to be "CVS ready"
- git commit -a               # edit the message to be "CVS ready"
- cd ~/sbcl-cvs
- GIT_DIR=~/sbcl-git/.git git cvsexportcommit -v foo-hacks-to-cvs
- review, fix any problems
+ git commit -a
+
+ # This exports our stuff to the CVS tree. HEAD can be any <<commit id>>,
+ # so if you have a large number of commits on a branch that you want to
+ # commit to CVS one by one, you do that as well.
+ git sbcl-export HEAD
+
+ cd ../sbcl-cvs
+
+ Review, fix problems, etc. Edit version.lisp-expr, and add the
+ version number to .msg (which contains the commit message from Git.)
+
  cvs commit -F .msg
 
 git-cvsexportcommit is fairly conservative by default, and will fail
@@ -270,9 +297,50 @@ issues manually:
  .msg                    -- holds the commit message
 
 Finally, delete the foo-hacks-to-cvs branch after you've committed
-code to CVS. Of course, instead of using git-cvexportcommit you can
+code to CVS. Of course, instead of using git-cvsexportcommit you can
 also manually make and apply patches, etc. For hairier cases it may
-even be easier in the end.
+even be easier in the end:
+
+  git format-patch -p master..foo-hacks
+
+Generates a patch for each commit between master and the HEAD of
+foo-hacks, naming them
+
+  0001-first-line-of-commit-message.patch
+  0002-and-so-and-so-forth.patch
+  ...
+
+Due to, among other things, the cvs->git synchronization lag it is
+easy to get conflicts on version.lisp-expr so generally speaking you
+never want to edit version-lisp.expr in Git, and only edit it (and add
+the version to the commit message) just when you are about to commit
+to CVS. It is, however, nice to have an idea how a given image came to
+be, which you can take care of by putting the following code in
+branch-version.lisp-expr:
+
+ #.(flet ((git (command &rest args)
+            (with-output-to-string (s)
+              ;; Adjust for your git installation location...
+              (sb-ext:run-program (merge-pathnames "bin/git" (user-homedir-pathname))
+                                  (cons command args) :output s))))
+     (format nil "~A.~A~@[-dirty~]"
+             (with-input-from-string (s (git "branch"))
+               (loop for line = (read-line s)
+                     when (eql #\* (char line 0))
+                     return (subseq line 2)))
+             (count #\newline (git "rev-list" "HEAD...master"))
+             (plusp (length (git "diff" "HEAD")))))
+
+which leads to your Git tree build to have version names like
+
+  1.0.20.28.master.0-dirty
+
+    1.0.20.28 on branch master, uncommitted changes
+
+  1.0.20.19.wip-foo.4
+
+    1.0.20.19 on branch wip-foo, 4 commits between current HEAD and
+    master, no uncommitted changes.
 
 To get latest changes from the CVS Git mirror you originally cloned
 from, do
@@ -281,18 +349,23 @@ from, do
 
 on the branch you want to update on your private repository.
 
+Note that if you edit version.lisp-expr in the CVS tree and not before
+then the cvs commit command that git-cvsexportcommit prints does not
+list version.lisp-expr, so don't copy paste it.
+
 This completes our whirlwind tour. I'm not saying this makes you
 proficient in using Git, but at least you should be up and walking.
 Reading
 
+ http://eagain.net/articles/git-for-computer-scientists/
  http://www.kernel.org/pub/software/scm/git/docs/everyday.html
+ http://www.kernel.org/pub/software/scm/git/docs/user-manual.html
 
-and
+and various Git manual pages is a good idea.
 
- http://eagain.net/articles/git-for-computer-scientists/
-and various Git manual pages is a good idea, as is building a decent
-mental model of the way Git actually works. One command I can in
-particular recommend getting familiar with is git-rebase. git-gui,
-git-citool, and gitk provide graphical interfaces for working with
-Git.
+Two commands I can in particular recommend getting familiar with are
+git-rebase and git-cherry-pick.
+
+git-gui, git-citool, and gitk provide graphical interfaces for
+working with Git -- particularly gitk is an invaluable tool for
+visualizing history.