Minor fix.
[gitmagic.git] / branch.txt
blob211bc10e22d43b4de174c9be7142837832ddf0cb
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
6 bug manifests in the released version without warning. The deadline for a
7 certain feature is moved closer. A developer whose help you need for a key section of the project is about to leave. In all cases, you must abruptly drop what you are doing and focus on a completely different task.
9 Interrupting your train of thought can be detrimental to your productivity, and the more cumbersome 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.
11 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.
13 *Solution*: Git has a better tool for these situations that is much faster and more space-efficient than cloning: *git branch*.
15 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.
17 === The Boss Key ===
19 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 it away?
21 In some directory:
23  $ echo "I'm smarter than my boss" > myfile.txt
24  $ git init
25  $ git add .
26  $ git commit -m "Initial commit"
28 We have created a Git repository that tracks one text file containing a certain message. Now type:
30  $ git checkout -b boss  # nothing seems to change after this
31  $ echo "My boss is smarter than me" > myfile.txt
32  $ git commit -a -m "Another commit"
34 It looks like we've just overwritten our file and committed it. But it's an illusion. Type:
36  $ git checkout master  # switch to original version of the file
38 and hey presto! The text file is restored. And if the boss decides to snoop around this directory, type:
40  $ git checkout boss  # switch to version suitable for boss' eyes
42 You can switch between the two versions of the file as much as you like, and commit to each independently.
44 === Dirty Work ===
46 [[branch]]
47 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:
49  $ git commit -a
50  $ git checkout SHA1_HASH
52 Now you can add ugly temporary code all over the place. You can even commit these changes. When you're done,
54  $ git checkout master
56 to return to your original work. Observe that any uncommitted changes are carried over.
58 What if you wanted to save the temporary changes after all? Easy:
60  $ git checkout -b dirty
62 and commit before switching back to the master branch. Whenever you want to return to the dirty changes, simply type
64  $ git checkout dirty
66 We touched upon this command in an earlier chapter, when discussing loading old states. At last we can tell the whole story: 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, which can be named later.
68 In other words, 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*.
70 === Quick Fixes ===
72 You're in the middle of something when you are told to drop everything and fix a newly discovered bug:
74  $ git commit -a
75  $ git checkout -b fixes SHA1_HASH
77 Then once you've fixed the bug:
79  $ git commit -a -m "Bug fixed"
80  $ git push  # to the central repository
81  $ git checkout master
83 and resume work on your original task.
85 === Uninterrupted Workflow ===
87 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.
89 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.
91 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:
93  $ git checkout -b part2
95 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,
97  $ git checkout master
98  $ git merge part2
99  $ git branch -d part2  # don't need this branch anymore
101 and the second part of the change is ready to review.
103 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
105  $ git checkout master
107 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:
109  $ git checkout part2
110  $ git merge master
112 Now it's the same as before. Once the first part has been approved and submitted:
114  $ git checkout master
115  $ git merge part2
116  $ git branch -d part2
118 and again, the second part is ready to be reviewed.
120 It's easy to extend this trick for any number of parts.
122 === Reorganizing a Medley ===
124 Perhaps you like to work on all aspects of a project in the same branch. You want to keep works-in-progress to yourself and want others to see your commits only when they have been neatly organized. Start a couple of branches:
126   $ git checkout -b sanitized
127   $ git checkout -b medley
129 Next, work on anything: fix bugs, add features, add temporary code, and so forth, committing often along the way. Then:
131   $ git checkout sanitized
132   $ git cherry-pick SHA1_HASH
134 applies a given commit to the "sanitized" branch. With appropriate cherry-picks you can construct a branch that contains only permanent code, and has related commits grouped together.
136 === Managing Branches ===
138 Type:
140  $ git branch
142 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.
144 The *-d* and *-m* options allow you to delete and move (rename) branches.
145 See *git help branch*.
147 === Temporary Branches ===
149 After a while you may realize you are creating short-lived branches
150 frequently for similar reasons: every other branch merely serves to
151 save the current state so you can briefly hop back to an older state to
152 fix a high-priority bug or something.
154 It's analogous to changing the TV channel temporarily to see what else is on.
155 But instead of pushing a couple of buttons, you have to create, check out and
156 delete temporary branches and commits. Luckily, Git has a shorcut that
157 is as convenient as a TV remote control:
159  $ git stash
161 This saves the current state in a temporary location (a 'stash') and
162 restores the previous state. Your working directory appears exactly as it was
163 before you started editing, and you can fix bugs, pull in upstream changes, and
164 so on. When you want to go back to the stashed state, type:
166  $ git stash apply  # You may need to resolve some conflicts.
168 You can have multiple stashes, and manipulate them in various ways. See
169 *git help stash*. As you may have guessed, Git maintains branches behind the scenes to perform this magic trick.
171 === Work How You Want ===
173 Applications such as http://www.mozilla.com/[Mozilla Firefox] allow you to open multiple tabs and multiple windows. Switching 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 improves the user experience.
175 On a higher level, several Linux window managers allow you to have multiple desktops: you can instantly switch to a different desktop. This is similar to branching in Git, whereas Git cloning would be like attaching another monitor to gain another desktop.
177 Yet another example is the http://www.gnu.org/software/screen/[*screen*] utility. This gem lets you 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 text.
179 Cloning, branching, and merging are fast and local in Git, encouraging you to use the combination that best suits you. Git lets you work exactly how you want.