From cca373577ff7c364e0c55a3e208ca17c110ef8de Mon Sep 17 00:00:00 2001 From: Ben Lynn Date: Sun, 2 Sep 2007 10:35:42 -0700 Subject: [PATCH] Wrote about branches --- Makefile | 3 ++- basic.txt | 4 +-- book.css | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ branch.txt | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++---------- clone.txt | 24 ++++++++++------- 5 files changed, 184 insertions(+), 26 deletions(-) create mode 100644 book.css diff --git a/Makefile b/Makefile index b6a3a37..8868ae0 100644 --- a/Makefile +++ b/Makefile @@ -7,10 +7,11 @@ TXTFILES=intro.txt basic.txt clone.txt branch.txt book.xml: $(TXTFILES) cat $^ | sed 's///g' | sed 's/<\/tt>/<\/command>/g' | ./bookmake > book.xml -book: book.xml +book: book.xml book.css xmlto -m custom-html.xsl -o book html book.xml -ls book/*.html | xargs -n 1 tidy -utf8 -m -i -q ./makeover + rsync book.css book/default.css book.html: book.xml xmlto -m custom-nochunks.xsl html-nochunks $^ diff --git a/basic.txt b/basic.txt index a82d961..e4e78b7 100644 --- a/basic.txt +++ b/basic.txt @@ -14,11 +14,11 @@ to take a snapshot of all files in the current directory. The above sequence of commands should be memorized, or placed in a script, as they will be reused frequently. -Then if something goes wrong type +Then if something goes wrong, run: $ git-checkout HEAD . -to go back to where you were. To save the state again, you can type +to go back to where you were. To save the state again: $ git-commit -a -m "another backup" diff --git a/book.css b/book.css new file mode 100644 index 0000000..25d7e1e --- /dev/null +++ b/book.css @@ -0,0 +1,89 @@ +body { + font-size: 90%; + font-family: verdana, arial, sans-serif; +} + +tt, code, pre, .type { + font-family: andale mono, courier new, courier, monospace; + font-size: 90%; +} + +/* Based on http://phrogz.net/CSS/columns3.html */ +div.toc { + float: left; + margin: 0; + padding: 0; + padding-top: 0.5em; + border: 0; + width: 13em; + + background-color: #f9f9f9; + margin-right:1em; +} + +div.content { + margin: 0; + padding: 0; + + /* won't match if font is smaller in toc */ + border-left: 13em solid #f9f9f9; + padding-left: 1em; +} + +div.content:after { + content:' '; + clear:both; + display:block; + height:0; + overflow:hidden +} + +div.footer { + clear:left; +} + +div.toc ul { + list-style: none; + padding: 0; + margin: 0; +} + +div.toc li ul a, li ul span.currentlink +{ + font-weight: normal; + font-size: 90%; + padding-left: 2em; +} + +div.toc a, span.currentlink{ + display:block; + text-decoration: none; + padding-left: 0.5em; + color: #0000aa; +} + +span.currentlink { + text-decoration: none; + background-color: #aaaaf9; +} + +div.toc a:visited { + color: #0000aa; +} + +div.toc a:hover { + background-color: #f9f9aa; +} + +.programlisting, .screen { + margin: 0; + border: 1px solid #aaaaaa; + background-color: #f9f9f9; + padding: 0.17em; + margin: 1em; + margin-right: 3em; +} + +.parameter { + font-style: italic; +} diff --git a/branch.txt b/branch.txt index 46c5afb..04ccc76 100644 --- a/branch.txt +++ b/branch.txt @@ -1,56 +1,118 @@ = Branch Magic = -Cheap Context Switching + +Now that you've mastered some simple Git sleights, it's time to learn some showstoppers. + +External factors inevitably necessitate context switching. A severe bug manifests in the released version suddenly without warning, and must be fixed as soon as possible at all costs. The guy who wrote a certain function is about to leave, so you should drop what you are doing and get him to help you with your changes that affect his code. + +Interrupting your train of thought can be detrimental to your productivity, and the slower and less convenient it is to switch contexts, the greater the loss. With centralized version control we must download a fresh working copy from the central server. Distributed systems fare much better, as we can clone the repository up to the desired version locally. + +But cloning still entails copying the whole working directory as well as the entire history up to the given point. Even though Git reduces the cost of this with file sharing and hard links, there are some files we cannot link nor share. The project files must be recreated in their entirety in the new working directory, so we may edit them. + +Happily, Git has a better tool for these situations that is much faster and more space-efficient than cloning: git-branch. == The Boss Key == Ever play one of those games where you could hit a special key combination at any time, and the screen would instantly display a spreadsheet or something? So if the boss walked in the office while you were playing the game you could quickly hide this fact? -In some directory, edit a text file and write "I'm smarter than my boss". -Create a Git repository, that is, git-init ; git-add . ; git-commit -m "Initial commit". Then type +In some directory: + + $ echo "I'm smarter than my boss" > myfile.txt + $ git-init-db + $ git-add . + $ git-commit -m "Initial commit" + +So we have created a Git repository that tracks one text file containing a certain message. Now type: - $ git checkout -b boss + $ git checkout -b boss # nothing seems to change after this + $ echo "My boss is smarter than me" > myfile.txt + $ git-commit -a -m "Another commit" -Edit the text file to say "My boss is smarter than me", and type git-commit -a. Now you can switch between the two versions of the file with +It looks like we've just overwritten our file and committed it. But it's an illusion. Type: - $ git branch master # see original version of the file + $ git checkout master # switch to original version of the file -and +and hey presto! The text file is restored. And if the boss decides to snoop around this directory, type: - $ git branch boss # see version of the file suitable for boss' eyes + $ git checkout boss # switch to version suitable for boss' eyes + +You can switch between the two versions of the file as much as you like, and commit to each independently. One can imagine reasons to use this that have nothing to do with source code management. Perhaps you have a program that reads data from a certain directory, and every now and then you'd like to switch the data back and forth without reconfiguring the program. == Dirty Work == -TODO +Say you're working on some feature, and for some reason, you need to go back to an old version and temporarily need to put in a few prints statements to see how something works. Then: + + $ git commit -a + $ git checkout -b dirty SHA1_HASH + +Now you can add ugly temporary code all over the place. When you're done, + + $ git checkout master + +to return to your original work, and: + + $ git branch -d dirty + +to remove the "dirty" branch, and all traces of the temporary code. == Quick Fixes == -TODO +This time, say you're in the middle of something and you are required to drop everything and work on fixing a bug that's just been reported: + + $ git commit -a + $ git checkout -b fixes SHA1_HASH + +Then once you've fixed the bug: + + $ git commit -a -m "bug fixed" + $ git push # to the central repository + $ git checkout master + +...and resume work on your original task. == Working While Being Reviewed == -Some projects require your code to be reviewed before you can submit it. To make life easier for those reviewing your code, if you have a big change to make you might break it into two or more parts, and get each parts separately reviewed. +Some projects require your code to be reviewed before you may submit it. To make life easier for those reviewing your code, if you have a big change to make you might break it into two or more parts, and get each parts separately reviewed. What if the second part cannot be written until the first part is approved and checked in? In many version control systems, you'd have to send the first part to the reviewers, and then wait until it has been approved before starting on the second part. -Actually that's not quite true, but in many systems editing part 2 before part 1 has been submitted involves a lot of suffering and hardship. In Git, branching and merging are painless. So after you've committed the first part and sent it for review: +Actually that's not quite true, but in these systems editing part two before part one has been submitted involves a lot of suffering and hardship. In Git, branching and merging are painless. So after you've committed the first part and sent it for review: $ git checkout -b part2 Next, code the second part of the big change while you're waiting for the first part to be accepted. When the first part is approved and submitted, - $ git branch master + $ git checkout master $ git merge part2 $ git branch -d part2 and the second part of the change is ready to review. -But wait! What if it wasn't that simple? Say you made a mistake in the first part, which you have to correct before submitting. No problem! First, switch back to the master branch with git branch master. Fix the issue with the first part of the change and hope it gets approved. If not we simply repeat this step. +But wait! What if it wasn't that simple? Say you made a mistake in the first part, which you have to correct before submitting. No problem! First, switch back to the master branch with + $ git checkout master + +Fix the issue with the first part of the change and hope it gets approved. If not we simply repeat this step. Eventually, once the first part has been approved and submitted: $ git merge part2 and again, the second part is ready to be reviewed. + +== Managing Branches == + +Type: + + $ git branch + +to list all the branches. There is always a branch named "master" which is where you start by default. This command can also do other operations with branches. See git help branch for details. + +== An Analogy == + +Several Linux window managers allow you to have multiple desktops, which means you can instantly view a different state of the desktop. + +Git branching is like multiple desktops for your working directory. With this analogy Git cloning is like attaching another monitor on which you can open more windows. + +Perhaps a better example is the famous [[http://TODO][screen]] utitlity. This gem allows you to create multiple terminal sessions in the same terminal. Instead of opening new terminals, you can use the same one if you run screen. In fact, you can do a lot more with screen but that's a topic for another day. diff --git a/clone.txt b/clone.txt index 692b33a..cff09cb 100644 --- a/clone.txt +++ b/clone.txt @@ -2,7 +2,7 @@ In older version control systems, checkout was the standard way to get a saved state. You'd checkout a bunch of files in the requested saved state. -In Git, the standard way to get files is to create a clone of the entire repository. In other words, you practically create a mirror of the central repository, so you can do anything the central repository can do. +In Git and other distributed version control systems, the standard way to get files is to create a clone of the entire repository. In other words, you practically create a mirror of the central repository. So anything the central repository can do, you can do. == Sync Computers == @@ -41,13 +41,13 @@ On the central server, initialize an empty Git repository with some name: $ GIT_DIR=proj.git git-init-db -Some public hosts, such as [[http://repo.or.cz][repo.or.cz]], will have alternative method for setting up the initially empty Git repository, such as filling in a form. +Some public hosts, such as [[http://repo.or.cz][repo.or.cz]], will have a different method for setting up the initially empty Git repository, such as filling in a form on a webpage. Push your project to the central server with: $ git-push git://central.server/path/to/proj.git HEAD -Now, to check out source, a developer types +We're ready. To check out source, a developer types $ git clone central.server:/path/to/proj.git @@ -81,6 +81,18 @@ If your project is not so popular, find as many hosts as you can and clone your For the truly paranoid, always write down the latest 20-byte SHA1 hash of the HEAD somewhere safe. It has to be safe, not private. For example, publishing it in a newspaper would work well, because it's hard for an attacker to alter every copy of a newspaper. +== Light-Speed Multitasking == + +Say you want to work on several features in parallel. Then after committing your project, clone it: + + $ git-clone --local --shared . /some/new/directory + +Git exploits hard links and file sharing as much as possible to create this clone. Subsequently, this clone is unsuitable as a backup. However, it's ready in a flash, and you can now you can work on two independent features simultaneously. + +For example, you can edit one while the other is compiling. At any time, you can commit and pull changes from one to the other. + + $ git-pull one /to/the/other + == Guerilla Version Control == Are you working on a project that uses some other version control system, and you sorely miss some Git features? Then initialize a Git repository in your working directory: @@ -105,9 +117,3 @@ Then go to the new directory and run: $ git pull On the other hand, the procedure for giving your changes to everyone else varies depending on the other version control system. You have the files you want to push in the new directory, and running a few commands of the other version control system will upload them to the central repository. - -== Multitasking == - -Say you want to work on several features in parallel. - -TODO -- 2.11.4.GIT