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:
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 gets tedious. Instead, you can type:
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 === I Stand Corrected ===
55 Did you just commit, but wish you had typed a different message? Realized you forgot to add a file? Then:
61 Since this changes the history, only do this if you have yet to push your changes, otherwise your tree will diverge from other trees. Of course, if you control all the other trees too, then there is no problem since you can overwrite them.
63 === ... And Then Some ===
65 Let's suppose the previous problem is ten times worse. After a lengthy session you've made a bunch of commits. But you're not quite happy with the way they're organized, and some of those commit messages could use rewording. This is quite likely if you've been saving early and saving often. Then type
67 $ git rebase -i HEAD~10
69 and the last 10 commits will appear in your favourite $EDITOR. A sample excerpt:
71 pick 5c6eb73 Added repo.or.cz link
72 pick a311a64 Reordered analogies in "Work How You Want"
73 pick 100834f Added push target to Makefile
77 - Remove commits by deleting lines.
78 - Reorder commits by reordering lines.
79 - Replace "pick" with "edit" to mark a commit for amending.
80 - Replace "pick" with "squash" to merge a commit with the previous one.
82 Next run *git commit \--amend* if you marked a commit for editing. Otherwise, run:
84 $ git rebase --continue
86 Thus tampering with the past is easily accomplished with the rebase command.
87 But take care: only rewrite that part of history which you alone possess. Just
88 as nations forever argue on who committed what atrocity, if someone else has a
89 clone whose version of history differs to yours, you will have trouble
90 reconciling when your trees interact.
92 Some developers strongly feel history should be immutable, warts and all.
93 What's done is done. Others feel trees should be made presentable before
94 they are unleashed in public. Git accommodates both viewpoints. Like cloning,
95 branching and merging, rewriting history is fast and local, and how you want to
96 use this power is up to you.
98 === Local Changes Last ===
100 You're working on an active project. You make some local commits over time, and
101 then you sync with the official tree with a merge. This cycle repeats itself a few times before you're ready to push to the central tree.
103 But now the history in your local Git clone is a messy jumble of your changes and the official changes. You'd prefer to see all your changes in one contiguous section, and after all the official changes.
105 This is a job for *git rebase* as described above. In many cases you can use
106 the *\--onto* flag and avoid interaction.
108 Also see the manpage for other amazing uses of this command, which really deserves a chapter of its own. You can split commits. You can even rearrange branches of a tree!
110 === My Commit Is Too Big! ===
112 Have you neglected to commit for too long? Been coding furiously and forgotten
113 about source control until now? Made a series of unrelated changes, because
120 For each edit you made, Git will show you the hunk of code that was changed,
121 and ask if it should be part of the next commit. Answer with "y" or "n". You
122 have other options, such as postponing the decision; type "?" to learn more.
124 Once you're satisfied, type
128 to commit precisely the changes you selected (the 'staged' changes). Make sure
129 you omit the *-a* option, otherwise Git will commit all the edits.
131 What if you've edited many files in many places? Reviewing each change one by
132 one becomes frustratingly mind-numbing. In this case, use *git add -i*, whose
133 interface is less straightforward, but more flexible. With a few keystrokes,
134 you can stage or unstage several files at a time, or review and select changes
135 in particular files only. Alternatively, run *git commit --interactive* which
136 automatically runs commits after you're done.
138 === Don't Lose Your HEAD ===
140 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:
144 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.
146 But how can you go back to the future? The past commits do not know anything of the future.
148 If you have the SHA1 of the original HEAD then:
152 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:
154 $ git reset ORIG_HEAD
158 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.
160 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.
162 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.
164 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.
166 The reflog command provides a friendly interface to these log files. Try
170 and see its manpage for more information.
172 Eventually, you may want to run *git gc \--prune* to recover space. Be aware that doing so prevents you from recovering lost HEADs.
174 === Making History ===
176 Want to migrate a project to Git? If it's managed with one of the more well-known systems, then chances are someone has already written a script to export the whole history to Git.
178 Otherwise, take a look at *git fast-import*. This command takes text input in a specific format and creates Git history from scratch. Typically a script is cobbled together and run once to feed this command, migrating the project in a single shot.
180 As an example, paste the following listing into temporary file, such as `/tmp/history`:
181 ----------------------------------
182 commit refs/heads/master
183 committer Alice <alice@example.com> Thu, 01 Jan 1970 00:00:00 +0000
188 M 100644 inline hello.c
193 printf("Hello, world!\n");
199 commit refs/heads/master
200 committer Bob <bob@example.com> Tue, 14 Mar 2000 01:59:26 -0800
202 Replace printf() with write().
205 M 100644 inline hello.c
210 write(1, "Hello, world!\n", 14);
215 ----------------------------------
217 Then create a Git repository from this temporary file by typing:
219 $ mkdir project; cd project; git init
220 $ git fast-import < /tmp/history
222 You can checkout the latest version of the project with:
224 $ git checkout master .
226 === Building On Git ===
228 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.
230 One easy trick is to use built-in git aliases shorten your most frequently used
233 $ git config --global alias.co checkout
234 $ git config --global --get-regexp alias # display current aliases
236 $ git co foo # same as 'git checkout foo'
238 Another is to print the current branch in the prompt, or window title.
241 $ git symbolic-ref HEAD
243 shows the current branch name. In practice, you most likely want to remove
244 the "refs/heads/" and ignore errors:
246 $ git symbolic-ref HEAD 2> /dev/null | cut -b 12-
248 See http://git.or.cz/[the Git homepage] for more examples.
250 === Daring Stunts ===
252 Recent versions of Git make it difficult for the user to accidentally destroy
253 data. This is perhaps the most compelling reason to upgrade. Nonetheless, there
254 are times you truly want to destroy data. We show how to override the
255 safeguards for common commands. Only use them if you know what you are doing.
257 *Checkout*: If you have uncommitted changes, a plain checkout fails. To destroy your changes, and checkout a given commit anyway, use the force flag:
259 $ git checkout -f COMMIT
261 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.
263 *Reset*: Reset also fails in the presence of uncommitted changes. To force it through, run:
265 $ git reset --hard [COMMIT]
267 *Branch*: Deleting branches fails if this causes changes to be lost. To force a deletion, type:
269 $ git branch -D BRANCH # instead of -d
271 Similarly, attempting to overwrite a branch via a move fails if data loss would ensue. To force a branch move, type:
273 $ git branch -M [SOURCE] TARGET # instead of -m
275 Unlike checkout and reset, these two commands defer data destruction. The
276 changes are still stored in the .git subdirectory, and can be retrieved by
277 recovering the appropriate hash from `.git/logs` (see "HEAD-hunting" above).
278 By default, they will be kept for at least two weeks.