Minor edits.
[gitmagic/gitmagic.git] / grandmaster.txt
blobca136c3ba8809c9e11927f9ea6068fe398a74886
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 your web server, but it does not have Git installed. Then download, compile and install Git in your account.
21 Create a repository in your web directory:
23  $ GIT_DIR=proj.git git init
25 and 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 === Commit What Changed ===
40 Telling Git when you've added, deleted and renamed files is troublesome for certain projects. Instead, you can type:
42  $ git add .
43  $ git add -u
45 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.
47 You can perform the above in a single pass with:
49  $ git ls-files -d -m -o -z | xargs -0 git update-index --add --remove
51 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.
53 === My Commit Is Too Big! ===
55 Have you neglected to commit for too long? Been coding furiously and forgotten
56 about source control until now? Made a series of unrelated changes, because
57 that's your style?
59 No worries. Run:
61  $ git add -p
63 For each edit you made, Git will show you the hunk of code that was changed,
64 and ask if it should be part of the next commit. Answer with "y" or "n". You
65 have other options, such as postponing the decision; type "?" to learn more.
67 Once you're satisfied, type
69  $ git commit
71 to commit precisely the changes you selected (the 'staged' changes). Make sure
72 you omit the *-a* option, otherwise Git will commit all the edits.
74 What if you've edited many files in many places? Reviewing each change one by
75 one becomes frustratingly mind-numbing. In this case, use *git add -i*, whose
76 interface is less straightforward, but more flexible. With a few keystrokes,
77 you can stage or unstage several files at a time, or review and select changes
78 in particular files only. Alternatively, run *git commit \--interactive* which
79 automatically runs commits after you're done.
81 === Don't Lose Your HEAD ===
83 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:
85  $ git reset HEAD~3
87 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.
89 But how can you go back to the future? The past commits do not know anything of the future.
91 If you have the SHA1 of the original HEAD then:
93  $ git reset SHA1
95 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:
97  $ git reset ORIG_HEAD
99 === HEAD-hunting ===
101 Perhaps ORIG_HEAD isn't enough. Perhaps you've just realized you made a monumental mistake last month and you need to go back to an ancient commit in a long-forgotten branch.
103 It's hard to lose Git commits permanently, even after deleting branches. As long as you never run *git gc \--prune*, your commits are preserved forever and can be restored at any time.
105 The trouble is finding the appropriate hash. You could look at all the hash values in `.git/objects` and use trial and error to find the one you want. But there's a much easier way.
107 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.
109 The reflog command provides a friendly interface to these log files. Try
111   $ git reflog
113 and see its manpage for more information.
115 Eventually, you may want to run *git gc \--prune* to recover space. Be aware that doing so prevents you from recovering lost HEADs.
117 === Building On Git ===
119 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.
121 One easy trick is to use built-in git aliases shorten your most frequently used
122 commands:
124   $ git config --global alias.co checkout
125   $ git config --global --get-regexp alias  # display current aliases
126   alias.co checkout
127   $ git co foo                              # same as 'git checkout foo'
129 Another is to print the current branch in the prompt, or window title.
130 Invoking
132   $ git symbolic-ref HEAD
134 shows the current branch name. In practice, you most likely want to remove
135 the "refs/heads/" and ignore errors:
137   $ git symbolic-ref HEAD 2> /dev/null | cut -b 12-
139 See http://git.or.cz/[the Git homepage] for more examples.
141 === Daring Stunts ===
143 Recent versions of Git make it difficult for the user to accidentally destroy
144 data. This is perhaps the most compelling reason to upgrade. Nonetheless, there
145 are times you truly want to destroy data. We show how to override the
146 safeguards for common commands. Only use them if you know what you are doing.
148 *Checkout*: If you have uncommitted changes, a plain checkout fails. To destroy your changes, and checkout a given commit anyway, use the force flag:
150   $ git checkout -f COMMIT
152 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.
154 *Reset*: Reset also fails in the presence of uncommitted changes. To force it through, run:
156   $ git reset --hard [COMMIT]
158 *Branch*: Deleting branches fails if this causes changes to be lost. To force a deletion, type:
160   $ git branch -D BRANCH  # instead of -d
162 Similarly, attempting to overwrite a branch via a move fails if data loss would ensue. To force a branch move, type:
164   $ git branch -M [SOURCE] TARGET  # instead of -m
166 Unlike checkout and reset, these two commands defer data destruction. The
167 changes are still stored in the .git subdirectory, and can be retrieved by
168 recovering the appropriate hash from `.git/logs` (see "HEAD-hunting" above).
169 By default, they will be kept for at least two weeks.