Minor fix.
[gitmagic.git] / grandmaster.txt
blob653bf0784d2c173bab0dcbc83fd690c3575de10f
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 the last to be
67 sent. The help page suggests using tags to solve this. Namely, after you
68 send a bundle, type:
70  $ git tag -f lastbundle HEAD
72 and create new refresher bundles with:
74  $ git bundle create newbundle HEAD ^lastbundle
76 === Commit What Changed ===
78 Telling Git when you've added, deleted and renamed files is troublesome for certain projects. Instead, you can type:
80  $ git add .
81  $ git add -u
83 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.
85 You can perform the above in a single pass with:
87  $ git ls-files -d -m -o -z | xargs -0 git update-index --add --remove
89 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.
91 === My Commit Is Too Big! ===
93 Have you neglected to commit for too long? Been coding furiously and forgotten
94 about source control until now? Made a series of unrelated changes, because
95 that's your style?
97 No worries. Run:
99  $ git add -p
101 For each edit you made, Git will show you the hunk of code that was changed,
102 and ask if it should be part of the next commit. Answer with "y" or "n". You
103 have other options, such as postponing the decision; type "?" to learn more.
105 Once you're satisfied, type
107  $ git commit
109 to commit precisely the changes you selected (the 'staged' changes). Make sure
110 you omit the *-a* option, otherwise Git will commit all the edits.
112 What if you've edited many files in many places? Reviewing each change one by
113 one becomes frustratingly mind-numbing. In this case, use *git add -i*, whose
114 interface is less straightforward, but more flexible. With a few keystrokes,
115 you can stage or unstage several files at a time, or review and select changes
116 in particular files only. Alternatively, run *git commit \--interactive* which
117 automatically runs commits after you're done.
119 === Don't Lose Your HEAD ===
121 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:
123  $ git reset HEAD~3
125 will move the HEAD three commits backwards in time. 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 git reset man page for some applications.
127 But how can you go back to the future? The past commits know nothing of the future.
129 If you have the SHA1 of the original HEAD then:
131  $ git reset SHA1
133 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:
135  $ git reset ORIG_HEAD
137 === HEAD-hunting ===
139 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.
141 By default, Git keeps a commit for at least two weeks, even if you ordered
142 Git to destroy the branch containing it. The trouble is finding the appropriate
143 hash. You could look at all the hash values in `.git/objects` and use trial
144 and error to find the one you want. But there's a much easier way.
146 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.
148 The reflog command provides a friendly interface to these log files. Try
150   $ git reflog
152 Instead of cutting and pasting hashes from the reflog, try:
154  $ git checkout "@{10 minutes ago}"
156 Or checkout the 5th-last visited commit via:
158  $ git checkout "@{5}"
160 See the ``Specifying Revisions'' section of *git help rev-parse* for more.
162 You may wish to configure a longer grace period for doomed commits. For
163 example:
165   $ git config gc.pruneexpire "30 days"
167 means a deleted commit will only be permanently lost once 30 days have passed
168 and *git gc* is run.
170 You may also wish to disable automatic invocations of *git gc*:
172   $ git conifg gc.auto 0
174 in which case commits will only be deleted when you run *git gc* manually.
176 === Building On Git ===
178 In true UNIX fashion, Git's design allows it to be easily used as a low-level component of other programs. There are GUI interfaces, web interfaces, alternative command-line interfaces, and perhaps soon you will have a script or two of your own that calls Git.
180 One easy trick is to use built-in git aliases shorten your most frequently used
181 commands:
183   $ git config --global alias.co checkout
184   $ git config --global --get-regexp alias  # display current aliases
185   alias.co checkout
186   $ git co foo                              # same as 'git checkout foo'
188 Another is to print the current branch in the prompt, or window title.
189 Invoking
191   $ git symbolic-ref HEAD
193 shows the current branch name. In practice, you most likely want to remove
194 the "refs/heads/" and ignore errors:
196   $ git symbolic-ref HEAD 2> /dev/null | cut -b 12-
198 See http://git.or.cz/[the Git homepage] for more examples.
200 === Daring Stunts ===
202 Recent versions of Git make it difficult for the user to accidentally destroy
203 data. This is perhaps the most compelling reason to upgrade. Nonetheless, there
204 are times you truly want to destroy data. We show how to override the
205 safeguards for common commands. Only use them if you know what you are doing.
207 *Checkout*: If you have uncommitted changes, a plain checkout fails. To destroy your changes, and checkout a given commit anyway, use the force flag:
209   $ git checkout -f COMMIT
211 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.
213 *Reset*: Reset also fails in the presence of uncommitted changes. To force it through, run:
215   $ git reset --hard [COMMIT]
217 *Branch*: Deleting branches fails if this causes changes to be lost. To force a deletion, type:
219   $ git branch -D BRANCH  # instead of -d
221 Similarly, attempting to overwrite a branch via a move fails if data loss would ensue. To force a branch move, type:
223   $ git branch -M [SOURCE] TARGET  # instead of -m
225 Unlike checkout and reset, these two commands defer data destruction. The
226 changes are still stored in the .git subdirectory, and can be retrieved by
227 recovering the appropriate hash from `.git/logs` (see "HEAD-hunting" above).
228 By default, they will be kept for at least two weeks.
230 *Clean*: Some git commands refuse to proceed because they're worried about
231 clobbering untracked files. If you're certain that all untracked files and
232 directories are expendable, then delete them mercilessly with:
234   $ git clean -f -d
236 Next time, that pesky command will work!