Added more git hosting sites.
[gitmagic/dustin.git] / branch.txt
blobb13f9cfd032a7ecdffe7651e314f74132d1b06d0
1 == Branch Wizardry ==
3 Instant branching and merging are the most lethal of Git's killer features.
5 *Problem*: 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 deadline for a certain feature is imminent. 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 understand it.
7 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 better, as we can clone the desired version locally.
9 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, the project files themselves must be recreated in their entirety in the new working directory.
11 *Solution*: Git has a better tool for these situations that is much faster and more space-efficient than cloning: *git-branch*.
13 With this magic word, the files in your directory suddenly shapeshift from one version to another. This transformation can do more than merely go back or forward in history. Your files can morph from the last release to the experimental version to the current development version to your friend's version and so on.
15 === The Boss Key ===
17 Ever play one of those games where at the push of a button ("the boss key"), 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?
19 In some directory:
21  $ echo "I'm smarter than my boss" > myfile.txt
22  $ git-init-db
23  $ git-add .
24  $ git-commit -m "Initial commit"
26 We have created a Git repository that tracks one text file containing a certain message. Now type:
28  $ git checkout -b boss  # nothing seems to change after this
29  $ echo "My boss is smarter than me" > myfile.txt
30  $ git-commit -a -m "Another commit"
32 It looks like we've just overwritten our file and committed it. But it's an illusion. Type:
34  $ git checkout master  # switch to original version of the file
36 and hey presto! The text file is restored. And if the boss decides to snoop around this directory, type:
38  $ git checkout boss  # switch to version suitable for boss' eyes
40 You can switch between the two versions of the file as much as you like, and commit to each independently.
42 === Dirty Work ===
44 Say you're working on some feature, and for some reason, you need to go back to an old version and temporarily put in a few prints statements to see how something works. Then:
46  $ git commit -a
47  $ git checkout SHA1_HASH
49 Now you can add ugly temporary code all over the place. When you're done,
51  $ git checkout master
53 to return to your original work and remove all traces of the temporary code.
55 What if you wanted to save the temporary changes after all? Easy:
57  $ git checkout -b dirty
59 before switching back to the master branch. Whenever you want to return to the dirty changes, simply type
61  $ git checkout dirty
63 We touched upon this command in an earlier chapter, when discussing loading old states. Now we can describe what happens when you load an old state using the checkout command: the files change to the requested state, but we must leave the master branch. Any commits made from now on take your files down a different road.
65 Hence after checking out an old state, Git automatically puts you in a new, unnamed branch, which can be named and saved with *git-checkout -b*.
67 === Quick Fixes ===
69 You're in the middle of something when you are told to drop everything and fix a newly discovered bug:
71  $ git commit -a
72  $ git checkout -b fixes SHA1_HASH
74 Then once you've fixed the bug:
76  $ git commit -a -m "bug fixed"
77  $ git push  # to the central repository
78  $ git checkout master
80 and resume work on your original task.
82 === Uninterrupted Workflow ===
84 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 part separately reviewed.
86 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.
88 Actually that's not quite true, but in these systems editing Part II before Part I has been submitted involves a lot of suffering and hardship. In Git, branching and merging are painless (a technical term for fast and local). So after you've committed the first part and sent it for review:
90  $ git checkout -b part2
92 Next, code the second part of the big change without waiting for the first part to be accepted. When the first part is approved and submitted,
94  $ git checkout master
95  $ git merge part2
96  $ git branch -d part2  # don't need this branch anymore
98 and the second part of the change is ready to review.
100 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
102  $ git checkout master
104 Fix the issue with the first part of the change and hope it gets approved. If not we simply repeat this step. You'll probably want to merge the fixed version of Part I into Part II as well:
106  $ git checkout part2
107  $ git merge master
109 Now it's the same as before. Once the first part has been approved and submitted:
111  $ git checkout master
112  $ git merge part2
113  $ git branch -d part2
115 and again, the second part is ready to be reviewed.
117 It's easy to extend this trick for any number of parts.
119 === Managing Branches ===
121 Type:
123  $ git branch
125 to list all the branches. There is always a branch named "master", and you start here by default. Some advocate leaving the "master" branch untouched and creating new branches for your own edits.
127 The branch command can also do other operations with branches. See *git help branch* for details.
129 === Work How You Want ===
131 Applications like http://www.mozilla.com/[Mozilla Firefox] allow you to open multitple tabs and multiple windows. Swtiching tabs gives you different content in the same window. Git branching is like tabs for your working directory. Continuing this analogy, Git cloning is like opening a new window. Being able to do both easily makes for a better user experience.
133 On a higher level, several Linux window managers allow you to have multiple desktops, which means you can instantly view a different state of the desktop. This is similar to branching in Git, whereas Git cloning would be like attaching another monitor where you can open more windows.
135 Yet another example is the http://www.gnu.org/software/screen/[*screen*] utility. This gem allows you to create, destroy and switch between multiple terminal sessions in the same terminal. Instead of opening new terminals (clone), you can use the same one if you run *screen* (branch). In fact, you can do a lot more with *screen* but that's a topic for another day.
137 Cloning, branching and merging are fast and local in Git, encouraging you to use the combination that best suits you. Git allows you to work exactly how you want.
139 ==== Personal Experience ====
141 The equivalent of branching and cloning in centralized version control systems, when it exists, requires network communication. This automatically precludes working offline. Secondly, these systems need more expensive network infrastructure, especially as the number of users grows.
143 Lastly, and most importantly, these operations will be slower to some degree, usually to the point where users won't bother using them unless absolutely necessary. And when they absolutely have to run slow commands, productivity suffers because of an interrupted work flow.
145 I experienced these phenomena first-hand. Git was the first version control system I used, and I grew accustomed to it, taking many features for granted. I did not know what centralized systems were like, and assumed they were similar. Later, I was forced to use one because of a project I worked on.
147 Often I have a flaky internet connection. I didn't mind too much with Git but found development unbearable with a centralized system.
149 I found myself conditioned to avoid certain commands because of the latencies involved, which ultimately prevented me from following the work flow I wanted.
151 And when I had to run a slow command, the interruption to my train of thought dealt a disproportionate amount of damage. While waiting for server communcation to complete, I'd do something else to pass the time, such as check email or write documentation. By the time I returned to the original task, the command had already finished long ago, but I'd have to spend a long time trying to remember what I was doing.