--- /dev/null
+* Overview
+ Git is a distributed vesioning control system.
+* References
+** Overviews
+*** DONE [[http://importantshock.wordpress.com/2008/08/07/git-vs-mercurial/][Git vs. Mercurial blog entry: MacGyver vs. Bond]]
+ CLOSED: [2008-08-28 Thu 05:06]
+ - State "DONE" [2008-08-28 Thu 05:06]
+ - State "TODO" [2008-08-28 Thu 05:06]
+ A nice, touchy-feely intro to the difference between Git and
+ Mercurial. Despite the one-stop-shopping-appeal of Mercurial, I
+ will go with my command-line-linux-philosophy-loving,
+ blogs-with-nanoblogger heart and head into git-land.
+** Tutorials
+*** TODO [[http://rubinius.lighthouseapp.com/projects/5089/using-git][Rubinius git page]] Get going fast
+ - State "TODO" [2008-08-28 Thu 05:06]
+*** TODO [[http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html][gittutorial]] The official intro ;), looks fairly readable…
+ - State "TODO" [2008-08-28 Thu 05:11]
+*** TODO [[http://www.kernel.org/pub/software/scm/git/docs/everyday.html][Everyday GIT With 20 Commands Or So]] Nicely broken down by goal
+ - State "TODO" [2008-08-28 Thu 05:06]
+*** TODO [[http://book.git-scm.com/][Git Community Book]] Open source wiki/howto website
+ - State "TODO" [2008-08-28 Thu 05:06]
+** Interface with SVN
+*** TODO [[http://newartisans.com/blog_files/diving.into.git.php][Diving into git blog entry]] Importing the Subversion history
+ - State "TODO" [2008-08-28 Thu 05:06]
+*** TODO [[http://git.or.cz/course/svn.html][Git - SVN Crash Course]] ?
+ - State "TODO" [2008-08-28 Thu 05:06]
+
+*** TODO [[http://utsl.gen.nz/talks/git-svn/intro.html][An introduction to git-svn for Subversion/SVK users and deserters]]
+ - State "TODO" [2008-08-28 Thu 06:09]
+ Lots of political digression, but also lots of useful info. Your call.
+** Enforcing development policies
+*** TODO [[http://www.kernel.org/pub/software/scm/git/docs/howto/update-hook-example.txt][Push hooks]]
+ - State "TODO" [2008-08-28 Thu 05:16]
+ Push hooks
+*** DONE [[http://blog.offbytwo.com/2008/04/16/running-nosetests-as-a-git-pre-commit-hook/][Pre commit hooks]]
+ CLOSED: [2008-09-02 Tue 08:48]
+ - State "DONE" [2008-09-02 Tue 08:48]
+ - State "TODO" [2008-09-02 Tue 08:46]
+ Basically, put whatever you want in .git/hooks/pre-commit.
+ For example, I added:
+
+ ./.git/hooks/pre-commit-make-check || exit 1
+
+ right after the initial comments with
+
+ $ cat .git/hooks/pre-commit-make-check
+ make check
+
+ Don't forget to chmod 744 both scripts to make them executible.
+ Also note that these scripts are run from the base repo directory,
+ which is why I had to include the relative path to
+ pre-commit-make-check, and didn't need `cd ../../' in the check
+ script.
+*** DONE [[http://changelog.complete.org/posts/586-Rebase-Considered-Harmful.html][Rebase Considered Harmful]]
+ CLOSED: [2008-08-28 Thu 05:27]
+ - State "DONE" [2008-08-28 Thu 05:27]
+ - State "TODO" [2008-08-28 Thu 05:18]
+
+ A “keep the warts” vs. “stay true to history” monologue.
+ Advocates against rebasing public repos because (quotes from the
+ git-rebase manpage):
+ "When you rebase a branch, you are changing its history in a way
+ that will cause problems for anyone who already has a copy of
+ the branch in their repository and tries to pull updates from
+ you."
+ Personally, I feel like a middle ground, where private
+ mini-branches get a little constructive history tweaking is a good
+ thing. Noone cares about typos in comments, and it adds noise to
+ the development signal, so fix those commits in your private
+ branch. Once you go public though, don't mess with the history,
+ since it would be even more confusing to have conflicting
+ histories in seperate public repositories. Anything serious
+ enough to require a altering the author field should probably not
+ be changed.
+
+ My thoughts are shared by others, for example commenter #7 Jing
+ Xue. However, commenter #8 links to [[http://www.reddit.com/r/programming/comments/6ube0/synchronizing_development_rebase_vs_pullmerge_git/?sort=top][Synchronizing development:
+ rebase vs. pull+merge, GIT vs. Mercurial]], where oddbod points
+ out that the real problem when “mid-level”, public repos rebase to
+ avoid sending known-bugged patches upstream. He says they avoid
+ the obviously better solution of sending up the bad patch with a
+ patch-patch hard on its heels, which would avoid rebasing a public
+ repo, and still preserve the spirit and authorship of the changes.
+**** Aside: rebase etymology
+ I just realized that “rebasing” is attaching your branch to a
+ different base point on the tree. Afterward, it looks like you
+ made all of your adjustments right now, not in parallel with
+ a bunch of other fixes on the main branch.
+** Setting a description for your repo
+ Edit .git/description
+* Peripherals
+** GitTorrent
+ People are indeed working on [[http://gittorrent.utsl.gen.nz/rfc.html][the obvious protocol]].
+* Case studies
+** Gitting chem_web, my first git project
+*** Repository creation and setup
+ Following the [[*Git Community Book]].
+*** Install
+ $ apt-get install git-core gitk
+*** Setup
+ from the [[http://book.git-scm.com/2_setup_and_initialization.html][Git Community Book]].
+
+ By default that file is ~/.gitconfig and the contents will then look like this:
+
+ [user]
+ name = W. Trevor King
+ email = wking at drexel dot edu
+*** Initialize repository
+ from the [[http://book.git-scm.com/3_getting_a_git_repository.html][Git Community Book]].
+
+ $ cd ~/rsrch/chem_web
+ $ git init
+*** Add some files to the repository
+ from the [[http://book.git-scm.com/3_normal_workflow.html][Git Community Book]].
+
+ $ git add README *.py docs templates
+ $ git status
+
+ Oops, git add add's all of a directory's contents too. Remove
+ some of the automatically generated files. `git rm' removes a
+ file from both the working directory and the index. I wish I
+ could just remove from the index, but I'm not sure how yet. Ah
+ well, the reason I want to remove them is that they are
+ automatically generated ;).
+
+ $ git rm -f docs/*.pdf
+ ...
+
+ a bunch of other work while I clean up the mess I've made. Keep
+ going until `git status' looks right.
+*** Commit the code to the master branch
+ from the [[http://book.git-scm.com/3_normal_workflow.html][Git Community Book]].
+
+ $ git commit
+
+ Or you can automatically add any changed tracked-files with
+
+ $ git commit -a
+*** Creating the development branch
+ from the [[http://book.git-scm.com/3_basic_branching_and_merging.html][Git Community Book]].
+
+ My workflow will be in two branches:
+ * master, the current stable/working release
+ * dev, the feature development branch
+
+ I will develop new code in the dev until I am happy with it's
+ performance, and then merge back into the master branch. Old bugs
+ will be fixed in the master branch, and then cherry-picked into
+ the dev branch. That's the current plan anyway ;). Create the
+ dev branch with
+
+ $ git branch dev
+*** Changing branches and coding
+ from the [[http://book.git-scm.com/3_basic_branching_and_merging.html][Git Community Book]].
+
+ List branches with
+
+ $ git branch
+
+ Change to dev with
+
+ $ git checkout dev
+
+ Now add that cool new feature, NFPA diamonds for the cabinets :p.
+ When you feel it is appropriate, commit your changes in the local
+ branch with
+
+ $ git commit -a
+*** Correcting private commit mistakes
+ from the [[http://book.git-scm.com/4_undoing_in_git_-_reset%2C_checkout_and_revert.html][Git Community Book]].
+
+ Oops, I forgot X or made a typo in my commit message.
+ My dev branch is not public, so go ahead and fix the mistake.
+ Then run
+
+ $ git commit --amend
+
+ This may leave some danglers
+
+ $ git fsck
+ dangling blob 03cabac5fa426ca8df4dff1fdb2596b68d2f4c5a
+ dangling blob 87488a0b4ea976127d6b9171ef6f10941a1dd74e
+ ...
+
+ which you can clean up with
+
+ $ git prune
+*** Bring the master branch up to speed
+ from the [[http://book.git-scm.com/3_basic_branching_and_merging.html][Git Community Book]].
+
+ $ git checkout master
+ $ git merge dev
+
+ You may have to deal with a [[*conflicting merge]].
+*** Delete a branch
+ from the [[http://book.git-scm.com/3_basic_branching_and_merging.html][Git Community Book]].
+
+ $ git branch -d dev
+
+ The `-d' ensures the changes have already been merged back into
+ the current branch. If you want to kill the brach without merging
+ use
+
+ $ git branch -D dev
+*** Repository maitenance
+ from the [[http://book.git-scm.com/4_maintaining_git.html][Git Community Boogk]].
+
+ Recompress (to keep the compression most effective)
+
+ $ git gc
+
+ Check repository consitency
+
+ $ git fsck
+
+ Both should be run manually from time to time.
+*** Working over a network
+ from the [[http://book.git-scm.com/3_distributed_workflows.html][Git Community Boogk]].
+**** Grab a remote repository
+ A remote friend wants to work on your code, or more likely, you're
+ at home and you want to work on your code at work. Grab the repo
+ using ssh with
+
+ $ git clone ssh://wking@loki/~/rsrch/chem_inventory ci
+
+ using the
+
+ ssh://[user@]host.xz/~/path/to/repo.git
+
+ git URL notation listed in man `git-clone'.
+**** Possibly remove the reference to the remote repository
+ If you're decomissioning the remote repository, you can remove it from
+ the current one with
+
+ git remote rm <name>
+**** Work on the repository
+ Nothing changes here.
+**** Get your remote partner to pull your changes back upstream
+
+ $ git remote add bob /home/bob/repo
+ $ git fetch remote
+ $ git log -p dev remotes/bob/master
+ $ git merge remotes/bob/master
+
+ and possibly
+
+ $ git remote rm bob
+** Gitting sawsim, migration from svn
+*** Install git
+ apt-get install git-core git-svn gitk
+*** Repository migration from svn
+ Following [[http://github.com/maddox][Jon Maddox]] at the [[http://www.simplisticcomplexity.com/2008/03/05/cleanly-migrate-your-subversion-repository-to-a-git-repository/][Simplistic Complexity blog]].
+**** Create the decoy directory
+ git-svn keeps some info about the svn repository, to make it
+ easier to keep the two in sync. However we are not interested in
+ staying in sync, we just want to move to git. Create a decoy git
+ version of the repo with
+
+ $ mkdir sawsim.svn
+ $ cd sawsim.svn
+ $ git-svn init svn://abax.physics.drexel.edu/sawsim/trunk/
+ $ cat >> .git/config <<EOF
+ [svn]
+ authorsfile = users.txt
+ EOF
+ $ cat > users.txt <<EOF
+ wking = W. Trevor King <wking at drexel dot edu>
+ EOF
+ $ git-svn fetch
+
+ Jon Maddox suggests using
+
+ $ git config svn.authorsfile ~/Desktop/users.txt
+
+ instead of my manual .git/config editing, but my stock Debian git
+ (1.4.4.4) doesn't seem to have git-config. No big deal.
+
+ Check that this worked and translated your users correctly with
+
+ $ git log
+***** Warning: here documents
+ Some shell's might not like my [[http://tldp.org/LDP/abs/html/here-docs.html][here document]] Bash syntax.
+ In that case, write the files another way.
+**** Create the clean directory
+ When we clone the decoy directory, all the svn junk gets left behind.
+
+ First, leave the sawsim.svn directory
+
+ $ cd ..
+
+ And clone like you normally would
+
+ $ git clone sawsim.svn sawsim
+
+ You don't need the [svn] stuff in .git/config anymore either.
+ I don't remember if they came over on their own or not…
+
+ I removed the origin information with
+
+ $ rm .git/remotes/origin
+*** Setup
+**** gitignore
+ from `man gitignore'
+
+ The sawsim code is mostly in a single now-web file. Extracting
+ all the source from the file creates lot of indirectly versioned
+ clutter. To avoid having all your `git status' calls swamped with
+ untracked files, Just add the filenames (globbing allowed) to
+ .gitignore.
+
+ The sawsim code is mostly in a single now-web file. Extracting
+ all the source from the file creates lot of indirectly versioned
+ clutter. To avoid having all your `git status' calls swamped with
+ untracked files, Just add the filenames (globbing allowed) to
+ .gitignore.
+**** [[Push hooks]]
+ TODO
+*** Making your repository public/Publishing your repository
+ From the [[http://book.git-scm.com/4_setting_up_a_public_repository.html][Git Community Book]]
+
+ To distribute your repo via HTTP (easier on someone else's server).
+
+ user@devel$ ssh server
+ server$ cd ~/public_html
+ server$ git clone --bare ssh://user@devel/~/path/to/repo.git repo.git
+ server$ cd repo.git
+ server$ touch git-daemon-export-ok
+ server$ git --bare update-server-info
+ server$ chmod a+x hooks/post-update
+
+ Others can clone or pull from your URL with
+
+ anon$ git clone http://server/~you/repo.git
+
+ from the [[http://book.git-scm.com/3_distributed_workflows.html][Git Community Book]]
+ Once you've set up your repo, you can push changes to it with ssh
+
+ devel$ git push ssh://user@server/~/public_html/repo.git master
+
+ To save typing, add
+
+ [remote "public"]
+ url = ssh://user@server/~/public_html/repo.git
+
+ to .git/config, after which you can push with
+
+ devel$ git push public master
+
+ Note that you may need to copy .git/description over by hand.
+ I wrote up a [[http://www.physics.drexel.edu/~wking/code/index.shtml#git-publish][git-publish]] script to automate this.
+** Gitting comedi, using Git as a frontend for CVS
+ http://issaris.blogspot.com/2005/11/cvs-to-git-and-back.html
+*** Repository creation and setup
+ This is quite similar to [[*Repository migration from svn]]
+**** Create the decoy directory
+ mkdir comedi.cvs
+ cd comedi.cvs
+ #cvs -d :pserver:anonymous@cvs.comedi.org:/cvs/comedi login
+ git-cvsimport -p x -v -d :pserver:anonymous@cvs.comedi.org:/cvs/comedi comedi
+
+ the login line may not be necessary for other CVS projects.
+ arguments to git-cvsimport
+ -p x (pass -x to cvsps, which ignores any ~/.cvsps/cvsps.cache file)
+ -v (verbose)
+ -d ... (from http://www.comedi.org/download.html)
+**** Create the clean directory
+ cd ..
+ git clone comedi.cvs comedi
+*** Do your work like normal in comedi
+*** Update with the latest cvs
+ $ cd comedi.cvs
+ $ git-cvsimport -p x -v -d :pserver:anonymous@cvs.comedi.org:/cvs/comedi comedi
+ $ cd ../comedi
+ $ git pull
+
+ You may have to deal with a [[*conflicting merge]].
+*** Create a patch against the cvs source
+ git-format-patch origin
+* Other useful examples
+** Purge all knowledge of a given file or subdir from history
+ For example, in case you accidentally started versioning
+ /etc/shadow, or some other document containing sensative
+ information.
+
+ $ git filter-branch --index-filter 'git rm -rf --cached --ignore-unmatch /etc/shadow'
+ $ git reflog expire --expire=0 --all
+ $ git prune
+ $ git repack -adf
+** Rewrite the repository to look as if foodir/ had been its project root
+ Discarding all other history
+
+ $ git filter-branch --subdirectory-filter foodir -- --all
+** Cherry pick a commit from another repository
+ First, give the remote repository a nickname (optional)
+
+ $ git remote add bob /home/bob/myrepo
+
+ Then fetch the remote repo
+
+ $ git fetch bob
+
+ You can merge all the changes Bob made to his master branch with
+
+ $ git pull . remotes/bob/master
+
+ Or cherry-pick a particular one, e.g. commit 1d8fb1fe41dfc1b1eb38c7b5d574577c4b341c58
+
+ $ git cherry-pick 1d8fb1fe41dfc1b1eb38c7b5d574577c4b341c58
+
+ When a particular remote repo no longer contains interesting material,
+ you can purge the fetched tags and objects with
+
+ $ git remote rm bob
+ $ git remote prune bob
+** Move master.HEAD to a different location
+ Sometimes you screw up and want to drop the thread you've been
+ working on. Place the HEAD of the master branch on commit XYZ with
+
+ $ git checkout XYZ
+ $ git branch -D master
+ $ git branch master XYZ
+ $ git checkout master
+
+ Note that this may remove some information from your .git/config's
+ [branch "master"] entry. You should save your earlier .git/config
+ before doing it, and make any appropriate corrections afterwards.
+** Git submodules, nesting/tracking sub-repositories.
+ This is a nice way of grouping associated projects. The submodules
+ are included as stand-alone repositories, and the super-project has
+ pointers picking out a particular revision of each submoduel. See
+ the related [[*Git subtrees]] for an alternate approach.
+*** References
+ [[http://git.or.cz/gitwiki/GitSubmoduleTutorial][Git Wiki]]
+ [[http://book.git-scm.com/5_submodules.html][Git Book]]
+ [[http://speirs.org/2009/05/11/understanding-git-submodules/][Fraser Speirs: Understanding Git Submodules]]
+*** Setup a super-module
+ [[http://book.git-scm.com/5_submodules.html][Git Book]]
+
+ $ git submodule add ~/path/to/submoduleX $submoduleX
+
+ Warning: Do not use local URLs here if you plan to publish your
+ supermodule.
+
+ git submodule add
+ * clones the submodule under the current directory and by
+ default checks out the master branch.
+ * adds the submodule's clone path to the gitmodules file and
+ adds this file to the index, ready to be committed.
+ * adds the submodule's current commit ID to the index, ready to
+ be committed.
+
+ $ git submodule init
+*** Cloning a super-module
+ [[http://git.or.cz/gitwiki/GitSubmoduleTutorial][Git Wiki]]
+
+ Grab the content living in the super module itself
+
+ $ git clone ~/subtut/public/super
+
+ See how the submodules look
+
+ $ git submodule status
+ -d266b9873ad50488163457f025db7cdd9683d88b a
+ ...
+
+ Add submodule repository URLs to .git/config
+
+ $ git submodule init
+
+ Check that they're there if you like
+
+ $ git config -l
+ ...
+ submodule.a.url=/home/moses/subtut/public/a/.git
+
+ Now check out the reverenced submodules
+
+ $ git submodule update
+*** Changing submodules from supermodules
+ [[http://git.or.cz/gitwiki/GitSubmoduleTutorial][Git Wiki]]
+
+ To update a submodule, remember that it's just a checked-out
+ branch in your supermodule. Create and publish the change
+ using the usual method:
+
+ $ cd a
+ a$ git branch
+ * (no branch)
+ master
+ a$ git checkout master
+ a$ echo "adding a line again" >> a.txt
+ a$ git commit -a -m "Updated the submodule from within the superproject."
+ a$ git push
+ $ cd ..
+
+ Now point the supermodule at the new commit. Warning: don't use
+ `git add a/` or git will think you mean to add the contents of the
+ directory. For submodule updates, you must leave off the trailing
+ slash.
+
+ $ git add a
+ $ git commit -m "Updated submodule a."
+ $ git show
+ ...
+ diff --git a/a b/a
+ index d266b98..261dfac 160000
+ --- a/a
+ +++ b/a
+ @@ -1 +1 @@
+ -Subproject commit d266b9873ad50488163457f025db7cdd9683d88b
+ +Subproject commit 261dfac35cb99d380eb966e102c1197139f7fa24
+
+ Take a look at the submodule changes from the supermodule.
+
+ $ git submodule summary HEAD^
+ * a d266b98...261dfac (1):
+ > Updated the submodule from within the superproject.
+
+ Publish your updated supermodule.
+
+ $ git push
+*** Removing submodules
+ [[http://git.or.cz/gitwiki/GitSubmoduleTutorial][Git Wiki]]
+
+ 1. Delete the relevant line from the .gitmodules file.
+ 2. Delete the relevant section from .git/config.
+ 3. Run git rm --cached path_to_submodule (no trailing slash).
+ 4. Commit and delete the now untracked submodule files.
+*** Warnings
+ [[http://git.or.cz/gitwiki/GitSubmoduleTutorial][Git Wiki]]
+
+ It's not safe to run "git submodule update" if you've made changes
+ within a submodule. They will be silently overwritten:
+**** Example
+ [[http://git.or.cz/gitwiki/GitSubmoduleTutorial][Git Wiki]]
+
+ a$ cat a.txt
+ module a
+ a$ echo line added from private2 >> a.txt
+ a$ git commit -a -m "line added inside private2"
+ $ cd ..
+ $ git submodule update
+ Submodule path 'a': checked out 'd266b9873ad50488163457f025db7cdd9683d88b'
+ $ cat a/a.txt
+ module a
+
+ The changes are still visible in the submodule's reflog:
+
+ $ git log -g --pretty=oneline
+ d266b9873ad50488163457f025db7cdd9683d88b HEAD@{0}: checkout: moving to d266b9873ad50488163457f025db7
+ 4389b0d8e22e616c88a99ebd072cfebba40797ef HEAD@{1}: commit: line added inside private2
+ d266b9873ad50488163457f025db7cdd9683d88b HEAD@{2}: checkout: moving to d266b9873ad50488163457f025db7
+** Git subtrees, merging an entire repository into a subdirectory of your repository
+*** Setup
+ [[http://www.kernel.org/pub/software/scm/git/docs/howto/using-merge-subtree.html][kernel.org: merge-subtree]]
+
+ Name the other project "Bproject", and fetch.
+
+ $ git remote add -f Bproject /path/to/B
+
+ Prepare for the later step to record the result as a merge.
+ ("-s ours" selects the merge strategy as "keep our version")
+
+ $ git merge -s ours --no-commit Bproject/master
+
+ Read "master" branch of Bproject to the subdirectory "dir-B".
+
+ $ git read-tree --prefix=dir-B/ -u Bproject/master
+
+ Record the merge result.
+
+ $ git commit -m "Merge B project as our subdirectory"
+*** Keeping up to date with the sub-repository source
+ Maintain the result with subsequent pulls/merges using "subtree"
+
+ $ git pull -s subtree Bproject master
+*** Pulling changes back into the sub-repository source
+ [[http://github.com/apenwarr/git-subtree/tree/master][git-subtree]]
+
+ The super-project makes some local alterations. Pull/merge them
+ with git-subtree.
+** Backdating Git tags
+I rarely bother tagging my projects in the early stages. This is
+probably a mistake ;), but Git makes it easy to add backdated tags
+later on:
+
+$ GIT_COMMITTER_DATE="2006-10-02 10:31" git tag -s v1.0.1
+
+(from git tag --help). Note that you will probably be tagging a
+previous commit
+
+$ GIT_COMMITTER_DATE="2006-10-02 10:31" git tag -s v1.0.1 <commit>
+
+* Troubleshooting
+** Git commit hangs with no output
+ You probably corrupted something in .git.
+
+ git gc
+ git fsck
+
+ fixed the problem for me.
+
+git blame comedi/drivers/ni_mio_common.c da96d940a9353160390869c504bad73b909adfcb
+** Conflicting merge
+ git-pull or git-merge aborts with `merge-failed' or some such.
+ This leaves your checked out branch in a state where
+
+ $ git diff
+
+ shows the merge difficulties. You can either [[*abort the merge]], or
+ [[*merge by hand]].
+*** Abort the merge
+ $ git reset --hard
+*** Merge by hand
+ Edit the marked packages as you see fit. Then let Git know you've
+ accepted your changes with either
+
+ $ git update-index
+
+ or
+
+ $ git add CONFLICT_FILE
+
+ Then commit with
+
+ $ git commit -a