Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 233 lines (147 sloc) 9.882 kb
7bff927 Converted to AsciiDoc
Ben Lynn authored
1 == Git Grandmastery ==
f9c9a82 Added two chapters
Ben Lynn authored
2
5a7b693 @blynn Reworded Git Grandmastery intro.
authored
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.
f9c9a82 Added two chapters
Ben Lynn authored
7
7bff927 Converted to AsciiDoc
Ben Lynn authored
8 === Source Releases ===
d774f92 Many minor edits
Ben Lynn authored
9
feed681 @blynn Split Grandmastery chapter.
authored
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:
d774f92 Many minor edits
Ben Lynn authored
12
ac0dc8d Fixed == typo.
Ben Lynn authored
13 $ git archive --format=tar --prefix=proj-1.2.3/ HEAD
d774f92 Many minor edits
Ben Lynn authored
14
7bff927 Converted to AsciiDoc
Ben Lynn authored
15 === Commit What Changed ===
f9c9a82 Added two chapters
Ben Lynn authored
16
feed681 @blynn Split Grandmastery chapter.
authored
17 Telling Git when you've added, deleted and renamed files is troublesome for
18 certain projects. Instead, you can type:
f9c9a82 Added two chapters
Ben Lynn authored
19
811da2e @blynn Added simpler solution to Commit What Changed.
authored
20 $ git add .
21 $ git add -u
f9c9a82 Added two chapters
Ben Lynn authored
22
feed681 @blynn Split Grandmastery chapter.
authored
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.
f9c9a82 Added two chapters
Ben Lynn authored
27
811da2e @blynn Added simpler solution to Commit What Changed.
authored
28 You can perform the above in a single pass with:
f9c9a82 Added two chapters
Ben Lynn authored
29
811da2e @blynn Added simpler solution to Commit What Changed.
authored
30 $ git ls-files -d -m -o -z | xargs -0 git update-index --add --remove
db3ff41 Wrote "Don't Lose Your HEAD"
Ben Lynn authored
31
feed681 @blynn Split Grandmastery chapter.
authored
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.
d774f92 Many minor edits
Ben Lynn authored
35
15f2b01 Aliases, printing current branch
Ben Lynn authored
36 === My Commit Is Too Big! ===
37
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?
41
4066153 @blynn Added section on stash command.
authored
42 No worries. Run:
15f2b01 Aliases, printing current branch
Ben Lynn authored
43
4066153 @blynn Added section on stash command.
authored
44 $ git add -p
45
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.
49
50 Once you're satisfied, type
51
52 $ git commit
10de9bb @blynn Mentioned clean, fixed whitespace issues.
authored
53
4066153 @blynn Added section on stash command.
authored
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.
796e8cb @blynn Described git add -p, mentioned git branch -d, -m.
authored
56
57 What if you've edited many files in many places? Reviewing each change one by
4066153 @blynn Added section on stash command.
authored
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
5180786 @blynn Spun off some sections into a new chapter on history operations.
authored
61 in particular files only. Alternatively, run *git commit \--interactive* which
88be878 @blynn Minor tweaks.
authored
62 automatically commits after you're done.
10de9bb @blynn Mentioned clean, fixed whitespace issues.
authored
63
477891e @blynn Converted most subsections to sections.
authored
64 === The Index: Git's Staging Area ===
6151e62 @blynn Briefly explain the index.
authored
65
e9561dc @blynn Minor changes.
authored
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.
6151e62 @blynn Briefly explain the index.
authored
71
88be878 @blynn Minor tweaks.
authored
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*.
6151e62 @blynn Briefly explain the index.
authored
77
5a7b693 @blynn Reworded Git Grandmastery intro.
authored
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.
6151e62 @blynn Briefly explain the index.
authored
79
7bff927 Converted to AsciiDoc
Ben Lynn authored
80 === Don't Lose Your HEAD ===
db3ff41 Wrote "Don't Lose Your HEAD"
Ben Lynn authored
81
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:
83
84 $ git reset HEAD~3
85
d63b428 @blynn How the object database works, with an example.
authored
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.
db3ff41 Wrote "Don't Lose Your HEAD"
Ben Lynn authored
87
a3dcb00 @blynn Moved Personal Experience section to chapter on history.
authored
88 But how can you go back to the future? The past commits know nothing of the future.
db3ff41 Wrote "Don't Lose Your HEAD"
Ben Lynn authored
89
90 If you have the SHA1 of the original HEAD then:
91
839f7e0 @blynn Minor edits.
authored
92 $ git reset 1b6d
db3ff41 Wrote "Don't Lose Your HEAD"
Ben Lynn authored
93
839f7e0 @blynn Minor edits.
authored
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:
db3ff41 Wrote "Don't Lose Your HEAD"
Ben Lynn authored
95
96 $ git reset ORIG_HEAD
97
925b297 Added HEAD-hunting section
Ben Lynn authored
98 === HEAD-hunting ===
99
a3dcb00 @blynn Moved Personal Experience section to chapter on history.
authored
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.
925b297 Added HEAD-hunting section
Ben Lynn authored
101
a3dcb00 @blynn Moved Personal Experience section to chapter on history.
authored
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.
925b297 Added HEAD-hunting section
Ben Lynn authored
106
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.
108
a1b4fc5 @blynn Mentioned reflog.
authored
109 The reflog command provides a friendly interface to these log files. Try
110
111 $ git reflog
112
822304d @blynn Moved reflog-related commands out of Basic Tricks chapter.
authored
113 Instead of cutting and pasting hashes from the reflog, try:
114
115 $ git checkout "@{10 minutes ago}"
116
117 Or checkout the 5th-last visited commit via:
118
119 $ git checkout "@{5}"
a1b4fc5 @blynn Mentioned reflog.
authored
120
01cbdc8 @blynn Moved another line out of Basic Tricks chapter.
authored
121 See the ``Specifying Revisions'' section of *git help rev-parse* for more.
122
a3dcb00 @blynn Moved Personal Experience section to chapter on history.
authored
123 You may wish to configure a longer grace period for doomed commits. For
124 example:
125
126 $ git config gc.pruneexpire "30 days"
127
128 means a deleted commit will only be permanently lost once 30 days have passed
129 and *git gc* is run.
130
131 You may also wish to disable automatic invocations of *git gc*:
132
9872d7f @sunny256 Typo fixes.
sunny256 authored
133 $ git config gc.auto 0
a3dcb00 @blynn Moved Personal Experience section to chapter on history.
authored
134
135 in which case commits will only be deleted when you run *git gc* manually.
925b297 Added HEAD-hunting section
Ben Lynn authored
136
7bff927 Converted to AsciiDoc
Ben Lynn authored
137 === Building On Git ===
d774f92 Many minor edits
Ben Lynn authored
138
0b219a2 @blynn Elaborated "Building on Git" section.
authored
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.
d774f92 Many minor edits
Ben Lynn authored
140
0b219a2 @blynn Elaborated "Building on Git" section.
authored
141 One easy trick is to use built-in Git aliases to shorten your most frequently
142 used commands:
15f2b01 Aliases, printing current branch
Ben Lynn authored
143
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'
148
149 Another is to print the current branch in the prompt, or window title.
150 Invoking
151
4b7cccf @dustin Modernized command invocations a bit.
dustin authored
152 $ git symbolic-ref HEAD
15f2b01 Aliases, printing current branch
Ben Lynn authored
153
154 shows the current branch name. In practice, you most likely want to remove
155 the "refs/heads/" and ignore errors:
156
4b7cccf @dustin Modernized command invocations a bit.
dustin authored
157 $ git symbolic-ref HEAD 2> /dev/null | cut -b 12-
15f2b01 Aliases, printing current branch
Ben Lynn authored
158
e9561dc @blynn Minor changes.
authored
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+.
0b219a2 @blynn Elaborated "Building on Git" section.
authored
162
9872d7f @sunny256 Typo fixes.
sunny256 authored
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:
0b219a2 @blynn Elaborated "Building on Git" section.
authored
164
165 $ git-new-workdir an/existing/repo new/directory
166
c4b3698 @blynn Minor touch-ups.
authored
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.
a61e675 @blynn Safeguards, and how to override them.
authored
168
169 === Daring Stunts ===
170
e9561dc @blynn Minor changes.
authored
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.
a61e675 @blynn Safeguards, and how to override them.
authored
174
88be878 @blynn Minor tweaks.
authored
175 *Checkout*: Uncommitted changes cause checkout to fail. To destroy your changes, and checkout a given commit anyway, use the force flag:
a61e675 @blynn Safeguards, and how to override them.
authored
176
f8abd5a @blynn Made more examples concrete.
authored
177 $ git checkout -f HEAD^
a61e675 @blynn Safeguards, and how to override them.
authored
178
54bc7ea @blynn Elaborate on checkout safety.
authored
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.
180
a61e675 @blynn Safeguards, and how to override them.
authored
181 *Reset*: Reset also fails in the presence of uncommitted changes. To force it through, run:
182
839f7e0 @blynn Minor edits.
authored
183 $ git reset --hard 1b6d
a61e675 @blynn Safeguards, and how to override them.
authored
184
185 *Branch*: Deleting branches fails if this causes changes to be lost. To force a deletion, type:
186
f8abd5a @blynn Made more examples concrete.
authored
187 $ git branch -D dead_branch # instead of -d
a61e675 @blynn Safeguards, and how to override them.
authored
188
a1b4fc5 @blynn Mentioned reflog.
authored
189 Similarly, attempting to overwrite a branch via a move fails if data loss would ensue. To force a branch move, type:
a61e675 @blynn Safeguards, and how to override them.
authored
190
f8abd5a @blynn Made more examples concrete.
authored
191 $ git branch -M source target # instead of -m
a61e675 @blynn Safeguards, and how to override them.
authored
192
4066153 @blynn Added section on stash command.
authored
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.
10de9bb @blynn Mentioned clean, fixed whitespace issues.
authored
197
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:
201
202 $ git clean -f -d
203
204 Next time, that pesky command will work!
f6bc35c @blynn Wrote about hooks.
authored
205
839f7e0 @blynn Minor edits.
authored
206 === Preventing Bad Commits ===
f6bc35c @blynn Wrote about hooks.
authored
207
c4b3698 @blynn Minor touch-ups.
authored
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
f6bc35c @blynn Wrote about hooks.
authored
211 public record.
212
c4b3698 @blynn Minor touch-ups.
authored
213 If only I had bought idiot insurance by using a _hook_ to alert me about these problems:
f6bc35c @blynn Wrote about hooks.
authored
214
feed681 @blynn Split Grandmastery chapter.
authored
215 $ cd .git/hooks
216 $ cp pre-commit.sample pre-commit # Older Git versions: chmod +x pre-commit
f6bc35c @blynn Wrote about hooks.
authored
217
218 Now Git aborts a commit if useless whitespace or unresolved merge conflicts are
219 detected.
220
8a57425 @blynn Changed hook example.
authored
221 For this guide, I eventually added the following to the beginning of the
feed681 @blynn Split Grandmastery chapter.
authored
222 *pre-commit* hook to guard against absent-mindedness:
f6bc35c @blynn Wrote about hooks.
authored
223
8a57425 @blynn Changed hook example.
authored
224 if git ls-files -o | grep '\.txt$'; then
225 echo FAIL! Untracked .txt files.
f6bc35c @blynn Wrote about hooks.
authored
226 exit 1
227 fi
228
c4b3698 @blynn Minor touch-ups.
authored
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.
Something went wrong with that request. Please try again.