18df2b7c9e04b450d43b6a7d67ac49351a76c1d6
[gitmagic.git] / pl / grandmaster.txt
blob18df2b7c9e04b450d43b6a7d67ac49351a76c1d6
1 == Git Grandmastery ==
3 By now, you should be able to navigate the *git help* pages and understand
4 almost everything. However, pinpointing the exact command required to solve a
5 given problem can be tedious. Perhaps I can save you some time: below are some
6 recipes I have needed in the past.
8 === Source Releases ===
10 For my projects, Git tracks exactly the files I'd like to archive and release
11 to users. To create a tarball of the source code, I run:
13  $ git archive --format=tar --prefix=proj-1.2.3/ HEAD
15 === Commit What Changed ===
17 Telling Git when you've added, deleted and renamed files is troublesome for
18 certain projects. Instead, you can type:
20  $ git add .
21  $ git add -u
23 Git will look at the files in the current directory and work out the details by
24 itself. Instead of the second add command, run `git commit -a` if you also
25 intend to commit at this time. See *git help ignore* for how to specify files
26 that should be ignored.
28 You can perform the above in a single pass with:
30  $ git ls-files -d -m -o -z | xargs -0 git update-index --add --remove
32 The *-z* and *-0* options prevent ill side-effects from filenames containing
33 strange characters. As this command adds ignored files, you may want to use the
34 `-x` or `-X` option.
36 === My Commit Is Too Big! ===
38 Have you neglected to commit for too long? Been coding furiously and forgotten
39 about source control until now? Made a series of unrelated changes, because
40 that's your style?
42 No worries. Run:
44  $ git add -p
46 For each edit you made, Git will show you the hunk of code that was changed,
47 and ask if it should be part of the next commit. Answer with "y" or "n". You
48 have other options, such as postponing the decision; type "?" to learn more.
50 Once you're satisfied, type
52  $ git commit
54 to commit precisely the changes you selected (the 'staged' changes). Make sure
55 you omit the *-a* option, otherwise Git will commit all the edits.
57 What if you've edited many files in many places? Reviewing each change one by
58 one becomes frustratingly mind-numbing. In this case, use *git add -i*, whose
59 interface is less straightforward, but more flexible. With a few keystrokes,
60 you can stage or unstage several files at a time, or review and select changes
61 in particular files only. Alternatively, run *git commit \--interactive* which
62 automatically commits after you're done.
64 === The Index: Git's Staging Area ===
66 So far we have avoided Git's famous 'index', but we must now confront it to
67 explain the above. The index is a temporary staging area. Git seldom shuttles
68 data directly between your project and its history. Rather, Git first writes
69 data to the index, and then copies the data in the index to its final
70 destination.
72 For example, *commit -a* is really a two-step process. The first step places a
73 snapshot of the current state of every tracked file into the index. The second
74 step permanently records the snapshot now in the index. Committing without the
75 *-a* option only performs the second step, and only makes sense after running
76 commands that somehow change the index, such as *git add*.
78 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, so we 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.
80 === Don't Lose Your HEAD ===
82 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:
84  $ git reset HEAD~3
86 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.
88 But how can you go back to the future? The past commits know nothing of the future.
90 If you have the SHA1 of the original HEAD then:
92  $ git reset 1b6d
94 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:
96  $ git reset ORIG_HEAD
98 === HEAD-hunting ===
100 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.
102 By default, Git keeps a commit for at least two weeks, even if you ordered
103 Git to destroy the branch containing it. The trouble is finding the appropriate
104 hash. You could look at all the hash values in `.git/objects` and use trial
105 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 Instead of cutting and pasting hashes from the reflog, try:
115  $ git checkout "@{10 minutes ago}"
117 Or checkout the 5th-last visited commit via:
119  $ git checkout "@{5}"
121 See the ``Specifying Revisions'' section of *git help rev-parse* for more.
123 You may wish to configure a longer grace period for doomed commits. For
124 example:
126   $ git config gc.pruneexpire "30 days"
128 means a deleted commit will only be permanently lost once 30 days have passed
129 and *git gc* is run.
131 You may also wish to disable automatic invocations of *git gc*:
133   $ git config gc.auto 0
135 in which case commits will only be deleted when you run *git gc* manually.
137 === Building On Git ===
139 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.
141 One easy trick is to use built-in Git aliases to shorten your most frequently
142 used commands:
144   $ git config --global alias.co checkout
145   $ git config --global --get-regexp alias  # display current aliases
146   alias.co checkout
147   $ git co foo                              # same as 'git checkout foo'
149 Another is to print the current branch in the prompt, or window title.
150 Invoking
152   $ git symbolic-ref HEAD
154 shows the current branch name. In practice, you most likely want to remove
155 the "refs/heads/" and ignore errors:
157   $ git symbolic-ref HEAD 2> /dev/null | cut -b 12-
159 The +contrib+ subdirectory is a treasure trove of tools built on Git.
160 In time, some of them may be promoted to official commands. On Debian and
161 Ubuntu, this directory lives at +/usr/share/doc/git-core/contrib+.
163 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 repository:
165   $ git-new-workdir an/existing/repo new/directory
167 The new directory and the 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.
169 === Daring Stunts ===
171 These days, Git makes it difficult for the user to accidentally destroy data.
172 But if you know what you are doing, you can override safeguards for common
173 commands.
175 *Checkout*: Uncommitted changes cause checkout to fail. To destroy your changes, and checkout a given commit anyway, use the force flag:
177   $ git checkout -f HEAD^
179 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.
181 *Reset*: Reset also fails in the presence of uncommitted changes. To force it through, run:
183   $ git reset --hard 1b6d
185 *Branch*: Deleting branches fails if this causes changes to be lost. To force a deletion, type:
187   $ git branch -D dead_branch  # instead of -d
189 Similarly, attempting to overwrite a branch via a move fails if data loss would ensue. To force a branch move, type:
191   $ git branch -M source target  # instead of -m
193 Unlike checkout and reset, these two commands defer data destruction. The
194 changes are still stored in the .git subdirectory, and can be retrieved by
195 recovering the appropriate hash from `.git/logs` (see "HEAD-hunting" above).
196 By default, they will be kept for at least two weeks.
198 *Clean*: Some git commands refuse to proceed because they're worried about
199 clobbering untracked files. If you're certain that all untracked files and
200 directories are expendable, then delete them mercilessly with:
202   $ git clean -f -d
204 Next time, that pesky command will work!
206 === Preventing Bad Commits ===
208 Stupid mistakes pollute my repositories. Most frightening are missing files due
209 to a forgotten *git add*. Lesser transgressions are trailing whitespace and
210 unresolved merge conflicts: though harmless, I wish these never appeared on the
211 public record.
213 If only I had bought idiot insurance by using a _hook_ to alert me about these problems:
215  $ cd .git/hooks
216  $ cp pre-commit.sample pre-commit  # Older Git versions: chmod +x pre-commit
218 Now Git aborts a commit if useless whitespace or unresolved merge conflicts are
219 detected.
221 For this guide, I eventually added the following to the beginning of the
222 *pre-commit* hook to guard against absent-mindedness:
224  if git ls-files -o | grep '\.txt$'; then
225    echo FAIL! Untracked .txt files.
226    exit 1
227  fi
229 Several git operations support hooks; see *git help hooks*. We activated the
230 sample *post-update* hook earlier when discussing Git over HTTP. This runs
231 whenever the head moves. The sample post-update script updates files Git needs
232 for communication over Git-agnostic transports such as HTTP.