Moved ChangeLog generation tip.
[gitmagic.git] / en / grandmaster.txt
blob8ac805799372735134f5cbbe7145b2bd42114974
1 == Git Grandmastery ==
3 This pretentiously named page is my dumping ground for uncategorized Git tricks.
5 === Source Releases ===
7 For my projects, Git tracks exactly the files I'd like to archive and release to users. To create a tarball of the source code, I run:
9  $ git archive --format=tar --prefix=proj-1.2.3/ HEAD
11 === Git Over SSH, HTTP ===
13 Suppose you have ssh access to a web server, but Git is not installed. Though less efficient than its native protocol, Git can communicate over HTTP.
15 Download, compile and install Git in your account, and create a repository in your web directory:
17  $ GIT_DIR=proj.git git init
19 In the "proj.git" directory, run:
21  $ git --bare update-server-info
22  $ chmod a+x hooks/post-update
24 From your computer, push via ssh:
26  $ git push web.server:/path/to/proj.git master
28 and others get your project via:
30  $ git clone http://web.server/proj.git
32 === Git Over Anything ===
34 Want to synchronize repositories without servers, or even a network connection?
35 Need to improvise during an emergency?
36 We've seen <<makinghistory, *git fast-export* and *git fast-import* can convert
37 repositories to a single file and back>>. We could shuttle such files back and
38 forth to transport git repositories over any medium, but a more efficient tool
39 is *git bundle*.
41 The sender creates a 'bundle':
43  $ git bundle create somefile HEAD
45 then transports the bundle, +somefile+, to the other party somehow: email,
46 thumb drive, floppy disk, an *xxd* printout and an OCR machine,
47 reading bits over the phone, smoke signals, etc. The receiver retrieves
48 commits from the bundle by typing:
50  $ git pull somefile
52 The receiver can even do this from an empty repository. Despite its
53 size, +somefile+ contains the entire original git repository.
55 In larger projects, eliminate waste by bundling only changes the other
56 repository lacks:
58  $ git bundle create somefile HEAD ^COMMON_SHA1
60 If done frequently, one could easily forget which commit was last sent. The
61 help page suggests using tags to solve this. Namely, after you send a bundle,
62 type:
64  $ git tag -f lastbundle HEAD
66 and create new refresher bundles with:
68  $ git bundle create newbundle HEAD ^lastbundle
70 === Patches: The Global Currency ===
72 Patches are text representations of your changes that can be easily understood
73 by computers and humans alike. This gives them universal appeal. You can email a
74 patch to developers no matter what version control system they're using. As long
75 as your audience can read their email, they can see your edits. Similarly, on
76 your side, all you require is an email account: there's no need to setup an online Git repository.
78 Recall from the first chapter:
80  $ git diff COMMIT
82 outputs a patch which can be pasted into an email for discussion. In a Git
83 repository, type:
85  $ git apply < FILE
87 to apply the patch.
89 In more formal settings, when author names and perhaps signatures should be
90 recorded, generate the corresponding patches past a certain point by typing:
92  $ git format-patch START_COMMIT
94 The resulting files can be given to *git-send-email*, or sent by hand. You can also specify a range of commits:
96  $ git format-patch START_COMMIT..END_COMMIT
98 On the receving end, save an email to a file, then type:
100  $ git am < FILE
102 This applies the incoming patch and also creates a commit, including information such as the author.
104 With a browser email client, you may need to click a button to see the email in its raw original form before saving the patch to a file.
106 There are slight differences for mbox-based email clients, but if you use one
107 of these, you're probably the sort of person who can figure them out easily
108 without reading tutorials!
110 === Sorry, We've Moved ===
112 From earlier chapters, we've seen that after cloning a repository, running
113 *git push* or *git pull* will automatically push to or pull from the original
114 URL. How does Git do this? The secret lies in config options initialized
115 created with the clone. Let's take a peek:
117  $ git config --list
119 The +remote.origin.url+ option controls the source URL; "origin" is a nickname
120 given to the source repository. As with the "master" branch convention, we may
121 change or delete this nickname but there is usually no reason for doing so.
123 If the the original repository moves, we can update the URL via:
125  $ git config remote.origin.url NEW_URL
127 The +branch.master.merge+ option specifies the default remote branch in
128 a *git pull*. During the initial clone, it is set to the current branch of the
129 source repository, so even if the HEAD of the source repository subsequently
130 moves to a different branch, a later pull will faithfully follow the
131 original branch.
133 This option only applies to the repository we first cloned from, which is
134 recorded in the option +branch.master.remote+. If we pull in from other
135 repositories we must explicitly state which branch we want:
137  $ git pull ANOTHER_URL master
139 The above explains why some of our earlier push and pull examples occasionally
140 required arguments.
142 === Remote Branches ===
144 When you clone a repository, you also clone all its branches. You may not have
145 noticed this because Git hides them away: you must ask for them specifically.
146 This prevents branches in the remote repository from interfering with
147 your branches, and also makes Git easier for beginners.
149 List the remote branches with:
151  $ git branch -r
153 You should see something like:
155  origin/HEAD
156  origin/master
157  origin/experimental
159 These represent branches and the HEAD of the remote repository, and can be used
160 in regular Git commands. For example, suppose you have made many commits, and
161 wish to compare against the last fetched version. You could search through the
162 logs for the appropriate SHA1 hash, but it's much easier to type:
164  $ git diff origin/HEAD
166 Or you can see what the "experimental" branch has been up to:
168  $ git log origin/experimental
170 === Multiple Remotes ===
172 Suppose two other developers are working on our project, and we want to
173 keep tabs on both. We can follow more than one repository at a time with:
175  $ git remote add other ANOTHER_URL
176  $ git pull other some_branch
178 Now we have merged in a branch from the second repository, and we have
179 easy access to all branches of all repositories:
181  $ git diff origin/experimental^ other/some_branch~5
183 But what if we just want to compare their changes without affecting our own
184 work? In other words, we want to examine their branches without having
185 their changes invade our working directory. In this case, rather than pull,
186 run:
188  $ git fetch        # Fetch from origin, the default.
189  $ git fetch other  # Fetch from the second programmer.
191 This fetches their histories and nothing more, so although the working
192 directory remains untouched, we can refer to any branch of any repository in
193 a Git command. By the way, behind the scenes, a pull is simply a fetch followed
194 by *git merge*; recall the latter merges a given commit into the working
195 directory. Usually we pull because we want to merge after a fetch; this
196 situation is a notable exception.
198 See *git help remote* for how to remove remote repositories, ignore certain
199 branches, and more.
201 === Commit What Changed ===
203 Telling Git when you've added, deleted and renamed files is troublesome for certain projects. Instead, you can type:
205  $ git add .
206  $ git add -u
208 Git will look at the files in the current directory and work out the details by itself. Instead of the second add command, run `git commit -a` if you also intend to commit at this time.
210 You can perform the above in a single pass with:
212  $ git ls-files -d -m -o -z | xargs -0 git update-index --add --remove
214 The *-z* and *-0* options prevent ill side-effects from filenames containing strange characters. Note this command adds ignored files. You may want to use the `-x` or `-X` option.
216 === My Commit Is Too Big! ===
218 Have you neglected to commit for too long? Been coding furiously and forgotten
219 about source control until now? Made a series of unrelated changes, because
220 that's your style?
222 No worries. Run:
224  $ git add -p
226 For each edit you made, Git will show you the hunk of code that was changed,
227 and ask if it should be part of the next commit. Answer with "y" or "n". You
228 have other options, such as postponing the decision; type "?" to learn more.
230 Once you're satisfied, type
232  $ git commit
234 to commit precisely the changes you selected (the 'staged' changes). Make sure
235 you omit the *-a* option, otherwise Git will commit all the edits.
237 What if you've edited many files in many places? Reviewing each change one by
238 one becomes frustratingly mind-numbing. In this case, use *git add -i*, whose
239 interface is less straightforward, but more flexible. With a few keystrokes,
240 you can stage or unstage several files at a time, or review and select changes
241 in particular files only. Alternatively, run *git commit \--interactive* which
242 automatically commits after you're done.
244 ==== Staged Changes ====
246 So far we have avoided Git's famous 'index', but we must now confront it to
247 explain the above. The index is a temporary staging area. Git seldom shuttles
248 data directly between your project and its history. Rather, Git first writes
249 data to the index, and then copies the data in the index to its final
250 destination.
252 For example, *commit -a* is really a two-step process. The first step places a
253 snapshot of the current state of every tracked file into the index. The second
254 step permanently records the snapshot now in the index. Committing without the
255 *-a* option only performs the second step, and only makes sense after running
256 commands that somehow change the index, such as *git add*.
258 Usually we can ignore the index and pretend we are reading straight from and writing straight to the history. On this occasion, we want finer control on what gets written to history, and are forced to manipulate the index. We place a snapshot of some, but not all, of our changes into the index, and then permanently record this carefully rigged snapshot.
260 === Don't Lose Your HEAD ===
262 The HEAD tag is like a cursor that normally points at the latest commit, advancing with each new commit. Some Git commands let you move it. For example:
264  $ git reset HEAD~3
266 will move the HEAD three commits back. Thus all Git commands now act as if you hadn't made those last three commits, while your files remain in the present. See the help page for some applications.
268 But how can you go back to the future? The past commits know nothing of the future.
270 If you have the SHA1 of the original HEAD then:
272  $ git reset SHA1
274 But suppose you never took it down? Don't worry, for commands like these, Git saves the original HEAD as a tag called ORIG_HEAD, and you can return safe and sound with:
276  $ git reset ORIG_HEAD
278 === HEAD-hunting ===
280 Perhaps ORIG_HEAD isn't enough. Perhaps you've just realized you made a monumental mistake and you need to go back to an ancient commit in a long-forgotten branch.
282 By default, Git keeps a commit for at least two weeks, even if you ordered
283 Git to destroy the branch containing it. The trouble is finding the appropriate
284 hash. You could look at all the hash values in `.git/objects` and use trial
285 and error to find the one you want. But there's a much easier way.
287 Git records every hash of a commit it computes in `.git/logs`. The subdirectory `refs` contains the history of all activity on all branches, while the file `HEAD` shows every hash value it has ever taken. The latter can be used to find hashes of commits on branches that have been accidentally lopped off.
289 The reflog command provides a friendly interface to these log files. Try
291   $ git reflog
293 Instead of cutting and pasting hashes from the reflog, try:
295  $ git checkout "@{10 minutes ago}"
297 Or checkout the 5th-last visited commit via:
299  $ git checkout "@{5}"
301 See the ``Specifying Revisions'' section of *git help rev-parse* for more.
303 You may wish to configure a longer grace period for doomed commits. For
304 example:
306   $ git config gc.pruneexpire "30 days"
308 means a deleted commit will only be permanently lost once 30 days have passed
309 and *git gc* is run.
311 You may also wish to disable automatic invocations of *git gc*:
313   $ git conifg gc.auto 0
315 in which case commits will only be deleted when you run *git gc* manually.
317 === Building On Git ===
319 In true UNIX fashion, Git's design allows it to be easily used as a low-level component of other programs, such as GUI and web interfaces, alternative command-line interfaces, patch managements tools, importing and conversion tools and so on. In fact, some Git commands are themselves scripts standing on the shoulders of giants. With a little tinkering, you can customize Git to suit your preferences.
321 One easy trick is to use built-in Git aliases to shorten your most frequently
322 used commands:
324   $ git config --global alias.co checkout
325   $ git config --global --get-regexp alias  # display current aliases
326   alias.co checkout
327   $ git co foo                              # same as 'git checkout foo'
329 Another is to print the current branch in the prompt, or window title.
330 Invoking
332   $ git symbolic-ref HEAD
334 shows the current branch name. In practice, you most likely want to remove
335 the "refs/heads/" and ignore errors:
337   $ git symbolic-ref HEAD 2> /dev/null | cut -b 12-
339 The +contrib+ subdirectory is a treasure trove of tools built on Git.
340 In time, some of them may be promoted to official commands. On Debian and
341 Ubuntu, this directory lives at +/usr/share/doc/git-core/contrib+.
343 One popular resident is +workdir/git-new-workdir+. Via clever symlinking, this script creates a new working directory whose history is shared with the original respository:
345   $ git-new-workdir an/existing/repo new/directory
347 The new directory and files within can be thought of as a clone, except since the history is shared, the two trees automatically stay in sync. There's no need to merge, push or pull.
349 === Daring Stunts ===
351 These days, Git makes it difficult for the user to accidentally destroy data.
352 But if you know what you are doing, you can override safeguards for common
353 commands.
355 *Checkout*: Uncommitted changes cause checkout to fail. To destroy your changes, and checkout a given commit anyway, use the force flag:
357   $ git checkout -f COMMIT
359 On the other hand, if you specify particular paths for checkout, then there are no safety checks. The supplied paths are quietly overwritten. Take care if you use checkout in this manner.
361 *Reset*: Reset also fails in the presence of uncommitted changes. To force it through, run:
363   $ git reset --hard [COMMIT]
365 *Branch*: Deleting branches fails if this causes changes to be lost. To force a deletion, type:
367   $ git branch -D BRANCH  # instead of -d
369 Similarly, attempting to overwrite a branch via a move fails if data loss would ensue. To force a branch move, type:
371   $ git branch -M [SOURCE] TARGET  # instead of -m
373 Unlike checkout and reset, these two commands defer data destruction. The
374 changes are still stored in the .git subdirectory, and can be retrieved by
375 recovering the appropriate hash from `.git/logs` (see "HEAD-hunting" above).
376 By default, they will be kept for at least two weeks.
378 *Clean*: Some git commands refuse to proceed because they're worried about
379 clobbering untracked files. If you're certain that all untracked files and
380 directories are expendable, then delete them mercilessly with:
382   $ git clean -f -d
384 Next time, that pesky command will work!
386 === Improve Your Public Image ===
388 Stupid mistakes abound in the histories of many of my projects. The most
389 frightening are missing files due to forgetting to run *git add*. Luckily I
390 have yet to lose crucial data though accidental omission because I rarely
391 delete original working directories. I typically notice the error a few commits
392 later, so the only damage is a bit of missing history and a sheepish admission
393 of guilt.
395 I also regularly commit (literally and git-erally) the lesser transgression of
396 trailing whitespace. Though harmless, I wish these also never appeared on the
397 public record.
399 In addition, though unscathed so far, I worry about leaving merge conflicts
400 unresolved. Usually I catch them when I build a project, but there are some
401 cases this can overlook.
403 If only I had bought idiot insurance by using a _hook_ to alert me about these
404 problems:
406  $ chmod +x .git/hooks/pre-commit
408 Now Git aborts a commit if useless whitespace or unresolved merge conflicts are
409 detected.
411 For a C project, add the following to the beginning of the *pre-commit* hook to
412 warn about forgotten files:
414  if git ls-files -o | grep '\.[ch]$'; then
415    echo FAIL! Looks like you forgot to add some source files.
416    exit 1
417  fi
419 Several git operations support hooks; see *git help hooks*. One can write hooks
420 to complain about spelling mistakes in commit messages, add new files, indent
421 paragraphs, complain about lines over 80 characters long, add an entry to a
422 webpage, play a sound, and so on.
424 In fact, we encountered the *post-update* hook while discussing Git over
425 HTTP: in this case, after the repository is updated, a hook script
426 maintains a few files Git needs for non-native communication.