Wrote about remote repositories.
[gitmagic.git] / en / grandmaster.txt
blob4858f09223268af8cd53ea1ff18df591f4314632
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 === Changelog Generation ===
13 It's good practice to keep a http://en.wikipedia.org/wiki/Changelog[changelog], and some projects even require it. If you've been committing frequently, which you should, generate a Changelog by typing:
15  $ git log > ChangeLog
17 === Git Over SSH, HTTP ===
19 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.
21 Download, compile and install Git in your account, and create a repository in your web directory:
23  $ GIT_DIR=proj.git git init
25 In the "proj.git" directory, run:
27  $ git --bare update-server-info
28  $ chmod a+x hooks/post-update
30 From your computer, push via ssh:
32  $ git push web.server:/path/to/proj.git master
34 and others get your project via:
36  $ git clone http://web.server/proj.git
38 === Git Over Anything ===
40 Want to synchronize repositories without servers, or even a network connection?
41 Need to improvise during an emergency?
42 We've seen <<makinghistory, *git fast-export* and *git fast-import* can convert
43 repositories to a single file and back>>. We could shuttle such files back and
44 forth to transport git repositories over any medium, but a more efficient tool
45 is *git bundle*.
47 The sender creates a 'bundle':
49  $ git bundle create somefile HEAD
51 then transports the bundle, +somefile+, to the other party somehow: email,
52 thumb drive, floppy disk, an *xxd* printout and an OCR machine,
53 reading bits over the phone, smoke signals, etc. The receiver retrieves
54 commits from the bundle by typing:
56  $ git pull somefile
58 The receiver can even do this from an empty repository. Despite its
59 size, +somefile+ contains the entire original git repository.
61 In larger projects, eliminate waste by bundling only changes the other
62 repository lacks:
64  $ git bundle create somefile HEAD ^COMMON_SHA1
66 If done frequently, one could easily forget which commit was last sent. The
67 help page suggests using tags to solve this. Namely, after you send a bundle,
68 type:
70  $ git tag -f lastbundle HEAD
72 and create new refresher bundles with:
74  $ git bundle create newbundle HEAD ^lastbundle
76 === Patches: The Global Currency ===
78 Patches are text representations of your changes that can be easily understood
79 by computers and humans alike. This gives them universal appeal. You can email a
80 patch to developers no matter what version control system they're using. As long
81 as your audience can read their email, they can see your edits. Similarly, on
82 your side, all you require is an email account: there's no need to setup an online Git repository.
84 Recall from the first chapter:
86  $ git diff COMMIT
88 outputs a patch which can be pasted into an email for discussion. In a Git
89 repository, type:
91  $ git apply < FILE
93 to apply the patch.
95 In more formal settings, when author names and perhaps signatures should be
96 recorded, generate the corresponding patches past a certain point by typing:
98  $ git format-patch START_COMMIT
100 The resulting files can be given to *git-send-email*, or sent by hand. You can also specify a range of commits:
102  $ git format-patch START_COMMIT..END_COMMIT
104 On the receving end, save an email to a file, then type:
106  $ git am < FILE
108 This applies the incoming patch and also creates a commit, including information such as the author.
110 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.
112 There are slight differences for mbox-based email clients, but if you use one
113 of these, you're probably the sort of person who can figure them out easily
114 without reading tutorials!
116 === Sorry, We've Moved ===
118 From earlier chapters, we've seen that after cloning a repository, running
119 *git push* or *git pull* will automatically push to or pull from the original
120 URL. How does Git do this? The secret lies in config options initialized
121 created with the clone. Let's take a peek:
123  $ git config --list
125 The +remote.origin.url+ option controls the source URL; "origin" is a nickname
126 given to the source repository. As with the "master" branch convention, we may
127 change or delete this nickname but there is usually no reason for doing so.
129 If the the original repository moves, we can update the URL via:
131  $ git config remote.origin.url NEW_URL
133 The +branch.master.merge+ option specifies the default remote branch in
134 a *git pull*. During the initial clone, it is set to the current branch of the
135 source repository, so even if the HEAD of the source repository subsequently
136 moves to a different branch, a later pull will faithfully follow the
137 original branch.
139 This option only applies to the repository we first cloned from, which is
140 recorded in the option +branch.master.remote+. If we pull in from other
141 repositories we must explicitly state which branch we want:
143  $ git pull ANOTHER_URL master
145 The above explains why some of our earlier push and pull examples occasionally
146 required arguments.
148 === Remote Branches ===
150 When you clone a repository, you also clone all its branches. You may not have
151 noticed this because Git hides them away: you must ask for them specifically.
152 This prevents branches in the remote repository from interfering with
153 your branches, and also makes Git easier for beginners.
155 List the remote branches with:
157  $ git branch -r
159 You should see something like:
161  origin/HEAD
162  origin/master
163  origin/experimental
165 These represent branches and the HEAD of the remote repository, and can be used
166 in regular Git commands. For example, suppose you have made many commits, and
167 wish to compare against the last fetched version. You could search through the
168 logs for the appropriate SHA1 hash, but it's much easier to type:
170  $ git diff origin/HEAD
172 Or quickly see what the "experimental" branch has been up to:
174  $ git log origin/experimental
176 === Multiple Remotes ===
178 Suppose two other developers are working on our project, and we want to
179 keep tabs on both. We can follow more than one repository at a time with:
181  $ git remote add other ANOTHER_URL
182  $ git pull other some_branch
184 Now we have merged in a branch from the second repository, and we have
185 easy access to all branches of all repositories:
187  $ git diff origin/experimental^ other/some_branch~5
189 But what if we just want to compare their changes without affecting our own
190 work? In other words, we want to examine their branches without having
191 their changes invade our working directory. In this case, rather than pull,
192 run:
194  $ git fetch        # Fetch from origin, the default.
195  $ git fetch other  # Fetch from the second programmer.
197 This fetches their histories and nothing more, so although the working
198 directory remains untouched, we can refer to any branch of any repository in
199 a Git command. By the way, behind the scenes, a pull is simply a fetch followed
200 by *git merge*; recall the latter merges a given commit into the working
201 directory. Usually we pull because we want to merge after a fetch; this
202 situation is a notable exception.
204 See *git help remote* for how to remove remote repositories, ignore certain
205 branches, and more.
207 === Commit What Changed ===
209 Telling Git when you've added, deleted and renamed files is troublesome for certain projects. Instead, you can type:
211  $ git add .
212  $ git add -u
214 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.
216 You can perform the above in a single pass with:
218  $ git ls-files -d -m -o -z | xargs -0 git update-index --add --remove
220 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.
222 === My Commit Is Too Big! ===
224 Have you neglected to commit for too long? Been coding furiously and forgotten
225 about source control until now? Made a series of unrelated changes, because
226 that's your style?
228 No worries. Run:
230  $ git add -p
232 For each edit you made, Git will show you the hunk of code that was changed,
233 and ask if it should be part of the next commit. Answer with "y" or "n". You
234 have other options, such as postponing the decision; type "?" to learn more.
236 Once you're satisfied, type
238  $ git commit
240 to commit precisely the changes you selected (the 'staged' changes). Make sure
241 you omit the *-a* option, otherwise Git will commit all the edits.
243 What if you've edited many files in many places? Reviewing each change one by
244 one becomes frustratingly mind-numbing. In this case, use *git add -i*, whose
245 interface is less straightforward, but more flexible. With a few keystrokes,
246 you can stage or unstage several files at a time, or review and select changes
247 in particular files only. Alternatively, run *git commit \--interactive* which
248 automatically commits after you're done.
250 ==== Staged Changes ====
252 So far I have deliberately avoided mentioning Git's famous 'index', but we must
253 now confront it to explain the above. The index is a temporary staging area.
254 Git seldom shuttles data directly between your project and its history. Rather,
255 Git first writes data to the index, and then copies the data in the index to
256 its final destination.
258 For example, *commit -a* is really a two-step process. The first step places a
259 snapshot of the current state of every tracked file into the index. The second
260 step permanently records the snapshot now in the index. Committing without the
261 *-a* option only performs the second step, and only makes sense after running
262 commands that somehow change the index, such as *git add*.
264 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.
266 === Don't Lose Your HEAD ===
268 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:
270  $ git reset HEAD~3
272 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.
274 But how can you go back to the future? The past commits know nothing of the future.
276 If you have the SHA1 of the original HEAD then:
278  $ git reset SHA1
280 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:
282  $ git reset ORIG_HEAD
284 === HEAD-hunting ===
286 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.
288 By default, Git keeps a commit for at least two weeks, even if you ordered
289 Git to destroy the branch containing it. The trouble is finding the appropriate
290 hash. You could look at all the hash values in `.git/objects` and use trial
291 and error to find the one you want. But there's a much easier way.
293 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.
295 The reflog command provides a friendly interface to these log files. Try
297   $ git reflog
299 Instead of cutting and pasting hashes from the reflog, try:
301  $ git checkout "@{10 minutes ago}"
303 Or checkout the 5th-last visited commit via:
305  $ git checkout "@{5}"
307 See the ``Specifying Revisions'' section of *git help rev-parse* for more.
309 You may wish to configure a longer grace period for doomed commits. For
310 example:
312   $ git config gc.pruneexpire "30 days"
314 means a deleted commit will only be permanently lost once 30 days have passed
315 and *git gc* is run.
317 You may also wish to disable automatic invocations of *git gc*:
319   $ git conifg gc.auto 0
321 in which case commits will only be deleted when you run *git gc* manually.
323 === Building On Git ===
325 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.
327 One easy trick is to use built-in Git aliases to shorten your most frequently
328 used commands:
330   $ git config --global alias.co checkout
331   $ git config --global --get-regexp alias  # display current aliases
332   alias.co checkout
333   $ git co foo                              # same as 'git checkout foo'
335 Another is to print the current branch in the prompt, or window title.
336 Invoking
338   $ git symbolic-ref HEAD
340 shows the current branch name. In practice, you most likely want to remove
341 the "refs/heads/" and ignore errors:
343   $ git symbolic-ref HEAD 2> /dev/null | cut -b 12-
345 The +contrib+ subdirectory is a treasure trove of tools built on basic commands
346 (which in time may be promoted to official commands). On Debian and Ubuntu,
347 this directory lives at +/usr/share/doc/git-core/contrib+.
349 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:
351   $ git-new-workdir an/existing/repo new/directory
353 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.
355 === Daring Stunts ===
357 Recent versions of Git make it difficult for the user to accidentally destroy
358 data. This is perhaps the most compelling reason to upgrade. Nonetheless, there
359 are times you truly want to destroy data. We show how to override the
360 safeguards for common commands. Only use them if you know what you are doing.
362 *Checkout*: Uncommitted changes cause checkout to fail. To destroy your changes, and checkout a given commit anyway, use the force flag:
364   $ git checkout -f COMMIT
366 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.
368 *Reset*: Reset also fails in the presence of uncommitted changes. To force it through, run:
370   $ git reset --hard [COMMIT]
372 *Branch*: Deleting branches fails if this causes changes to be lost. To force a deletion, type:
374   $ git branch -D BRANCH  # instead of -d
376 Similarly, attempting to overwrite a branch via a move fails if data loss would ensue. To force a branch move, type:
378   $ git branch -M [SOURCE] TARGET  # instead of -m
380 Unlike checkout and reset, these two commands defer data destruction. The
381 changes are still stored in the .git subdirectory, and can be retrieved by
382 recovering the appropriate hash from `.git/logs` (see "HEAD-hunting" above).
383 By default, they will be kept for at least two weeks.
385 *Clean*: Some git commands refuse to proceed because they're worried about
386 clobbering untracked files. If you're certain that all untracked files and
387 directories are expendable, then delete them mercilessly with:
389   $ git clean -f -d
391 Next time, that pesky command will work!