From 4b7cccfaf09d3fff50e702a820f3830206b153c0 Mon Sep 17 00:00:00 2001 From: Dustin Sallings Date: Sat, 12 Apr 2008 09:10:53 -0700 Subject: [PATCH] Modernized command invocations a bit. No more git- or init-db. --- basic.txt | 72 ++++++++++++++++++++++++++++----------------------------- branch.txt | 12 +++++----- clone.txt | 26 ++++++++++----------- grandmaster.txt | 28 +++++++++++----------- secrets.txt | 8 +++---- 5 files changed, 73 insertions(+), 73 deletions(-) diff --git a/basic.txt b/basic.txt index e5a619e..8aa9a32 100644 --- a/basic.txt +++ b/basic.txt @@ -6,9 +6,9 @@ Rather than diving into a sea of Git commands, use these elementary examples to When I'm about to attempt something drastic I like to save the current state, so I can go back and try again should things go awry. - $ git-init-db # for git-1.5 and up you can type "git-init" instead - $ git-add . - $ git-commit -m "my first backup" + $ git init + $ git add . + $ git commit -m "my first backup" to take a snapshot of all files in the current directory. @@ -16,65 +16,65 @@ The above sequence of commands should be memorized, or placed in a script, as th Then if something goes wrong, run: - $ git-reset --hard + $ git reset --hard to go back to where you were. To save the state again: - $ git-commit -a -m "another backup" + $ git commit -a -m "another backup" Tip: the hyphen after "git" may be replaced by a space if you prefer. ==== Add, Delete, Rename ==== -The above will only keep track of the files that were present when you first ran *git-add*. If you add new files or subdirectories, you'll have to tell Git: +The above will only keep track of the files that were present when you first ran *git add*. If you add new files or subdirectories, you'll have to tell Git: - $ git-add NEWFILES... + $ git add NEWFILES... Similarly, if you want Git to forget about certain files, maybe because you've deleted them - $ git-rm OLDFILES... + $ git rm OLDFILES... -Renaming a file is the same as removing the old name and adding the new name. There's also the shortcut *git-mv* which has the same syntax as the *mv* command. For example: +Renaming a file is the same as removing the old name and adding the new name. There's also the shortcut *git mv* which has the same syntax as the *mv* command. For example: - $ git-mv OLDFILE NEWFILE + $ git mv OLDFILE NEWFILE === Advanced Undo/Redo === Running: - $ git-log + $ git log shows you a list of recent commits, and their SHA1 hashes. Then: - $ git-commit -a - $ git-revert SHA1_HASH + $ git commit -a + $ git revert SHA1_HASH will load the previous state with the given hash. Don't like cutting and pasting hashes? Then use: - $ git-revert "@{10 minutes ago}" . + $ git revert "@{10 minutes ago}" . Other time specifications work too. Or you can ask for the 5th-last saved state: - $ git-revert "@{5}" . + $ git revert "@{5}" . -Running *git-log* reveals that the fact that you loaded an old saved state has been recorded as new commit. In other words, Git tracks your undo and redo operations. +Running *git log* reveals that the fact that you loaded an old saved state has been recorded as new commit. In other words, Git tracks your undo and redo operations. Sometimes you just want to go back and forget about every change past a certain point because they're all wrong. Then type: - $ git-reset --hard SHA1_HASH + $ git reset --hard SHA1_HASH which restores the state to a given commit and also erases all newer commits from the record permanently. -Using *git-checkout* is a third way to load an old state, but it's slightly more complicated because it involves branches, and will be discussed in detail later. +Using *git checkout* is a third way to load an old state, but it's slightly more complicated because it involves branches, and will be discussed in detail later. To take the computer game analogy again: -- *git-revert* is like loading a game and recording this fact as a new saved game, +- *git revert* is like loading a game and recording this fact as a new saved game, -- *git-reset --hard* is like loading an old save and deleting all saved games newer than the one just loaded, and +- *git reset --hard* is like loading an old save and deleting all saved games newer than the one just loaded, and -- *git-checkout* is like loading an old game, but if you play on, the game state will deviate from the newer saves you made the first time around. Any saved games you make now will end up in a separate branch representing the alternate reality you have entered. We describe how to deal with this later. +- *git checkout* is like loading an old game, but if you play on, the game state will deviate from the newer saves you made the first time around. Any saved games you make now will end up in a separate branch representing the alternate reality you have entered. We describe how to deal with this later. For reset and checkout, you can choose only to restore particular files and subdirectories by appending them after the command. @@ -82,19 +82,19 @@ For reset and checkout, you can choose only to restore particular files and subd If a project uses Git to manage its files, you can get a copy with: - $ git-clone git://server/path/to/files + $ git clone git://server/path/to/files For example, to get all the files I used to create this site: - $ git-clone git://git.or.cz/gitmagic.git + $ git clone git://git.or.cz/gitmagic.git We'll have a lot more to say about the *clone* command later. === The Bleeding Edge === -If a project uses Git to manage its files, and you've already downloaded a copy using *git-clone*, you can upgrade to the latest version with: +If a project uses Git to manage its files, and you've already downloaded a copy using *git clone*, you can upgrade to the latest version with: - $ git-pull + $ git pull === Instant Publishing === @@ -102,25 +102,25 @@ Let's say you've written a script you'd like to share with others. You could jus To do this with Git, in the directory where your script resides: - $ git-init-db # in git-1.5 just type git-init - $ git-add . - $ git-commit -m "first release" + $ git init + $ git add . + $ git commit -m "first release" Then tell your users to type - $ git-clone your.computer:/path/to/script + $ git clone your.computer:/path/to/script -to download your script. This assumes they have ssh access. If not, run *git-daemon* and tell your users to type +to download your script. This assumes they have ssh access. If not, run *git daemon* and tell your users to type - $ git-clone git://your.computer/path/to/script + $ git clone git://your.computer/path/to/script From now on, every time your script is ready for release, type: - $ git-commit -a -m "next release" + $ git commit -a -m "next release" and your users can upgrade their version by changing to the directory containing your script and typing. - $ git-pull + $ git pull Your users will never end up with a version of your script you don't want them to see. Obviously this trick works for anything, not just scripts. @@ -128,12 +128,12 @@ Your users will never end up with a version of your script you don't want them t Find out what changes you've made since the last commit with: - $ git-diff + $ git diff Or since yesterday: - $ git-diff "@{yesterday}" + $ git diff "@{yesterday}" Or between a particular version and 2 versions ago: - $ git-diff SHA1_HASH "@{2}" + $ git diff SHA1_HASH "@{2}" diff --git a/branch.txt b/branch.txt index d5311cc..7ff084a 100644 --- a/branch.txt +++ b/branch.txt @@ -8,7 +8,7 @@ Interrupting your train of thought can be detrimental to your productivity, and But cloning still entails copying the whole working directory as well as the entire history up to the given point. Even though Git reduces the cost of this with file sharing and hard links, the project files themselves must be recreated in their entirety in the new working directory. -*Solution*: Git has a better tool for these situations that is much faster and more space-efficient than cloning: *git-branch*. +*Solution*: Git has a better tool for these situations that is much faster and more space-efficient than cloning: *git branch*. With this magic word, the files in your directory suddenly shapeshift from one version to another. This transformation can do more than merely go back or forward in history. Your files can morph from the last release to the experimental version to the current development version to your friend's version and so on. @@ -19,15 +19,15 @@ Ever play one of those games where at the push of a button ("the boss key"), the In some directory: $ echo "I'm smarter than my boss" > myfile.txt - $ git-init-db - $ git-add . - $ git-commit -m "Initial commit" + $ git init + $ git add . + $ git commit -m "Initial commit" We have created a Git repository that tracks one text file containing a certain message. Now type: $ git checkout -b boss # nothing seems to change after this $ echo "My boss is smarter than me" > myfile.txt - $ git-commit -a -m "Another commit" + $ git commit -a -m "Another commit" It looks like we've just overwritten our file and committed it. But it's an illusion. Type: @@ -62,7 +62,7 @@ before switching back to the master branch. Whenever you want to return to the d We touched upon this command in an earlier chapter, when discussing loading old states. Now we can describe what happens when you load an old state using the checkout command: the files change to the requested state, but we must leave the master branch. Any commits made from now on take your files down a different road. -Hence after checking out an old state, Git automatically puts you in a new, unnamed branch, which can be named and saved with *git-checkout -b*. +Hence after checking out an old state, Git automatically puts you in a new, unnamed branch, which can be named and saved with *git checkout -b*. === Quick Fixes === diff --git a/clone.txt b/clone.txt index d5405be..25f2182 100644 --- a/clone.txt +++ b/clone.txt @@ -10,22 +10,22 @@ This is the reason I first used Git. I can tolerate making tarballs or using *rs Initialize a Git repository and commit your files as above on one machine. Then on the other: - $ git-clone other.computer:/path/to/files + $ git clone other.computer:/path/to/files to create a second copy of the files and Git respository. From now on, - $ git-commit -a - $ git-pull other.computer:/path/to/files + $ git commit -a + $ git pull other.computer:/path/to/files will pull in the state of the files on the other computer into the one you're working on. If you've recently made conflicting edits in the same file, Git will let you know and you should commit again after resolving them. Pushing is also possible. If you have not committed any changes on the other computer, you may type - $ git-push other.computer:/path/to/files + $ git push other.computer:/path/to/files to push the current state to the other computer. Next time you're logged in to the other computer, run - $ git-checkout HEAD . + $ git checkout HEAD . to update the files before working on them. Be aware that you'll lose any uncommitted changes when you do this. Because more care is required, I prefer sticking to pulls for this use case. @@ -33,21 +33,21 @@ to update the files before working on them. Be aware that you'll lose any uncomm Initialize a Git repository for your files: - $ git-init-db + $ git init $ git add . $ git commit -m "Initial commit" On the central server, initialize an empty Git repository with some name, and start the Git daemon if necessary: - $ GIT_DIR==proj.git git-init-db - $ git-daemon --detach # it might already be running + $ GIT_DIR==proj.git git init + $ git daemon --detach # it might already be running Some public hosts, such as http://repo.or.cz[repo.or.cz], will have a different method for setting up the initially empty Git repository, such as filling in a form on a webpage. Push your project to the central server with: - $ git-push git://central.server/path/to/proj.git HEAD + $ git push git://central.server/path/to/proj.git HEAD We're ready. To check out source, a developer types @@ -87,7 +87,7 @@ The truly paranoid should always write down the latest 20-byte SHA1 hash of the Say you want to work on several features in parallel. Then after committing your project: - $ git-clone --local --shared . /some/new/directory + $ git clone --local --shared . /some/new/directory The options can be written as *-l -s* instead, which I like to think of as an acronym for "Light Speed"! @@ -95,19 +95,19 @@ Git exploits hard links and file sharing as much as possible to create this clon At any time, you can commit and pull changes from the other clone. - $ git-pull /the/other/clone + $ git pull /the/other/clone === Guerilla Version Control === Are you working on a project that uses some other version control system, and you sorely miss Git? Then initialize a Git repository in your working directory: - $ git-init-db + $ git init $ git add . $ git commit -m "Initial commit" then clone it, at light speed: - $ git-clone -l -s . /some/new/directory + $ git clone -l -s . /some/new/directory Now go to the new directory and work here instead, using Git to your heart's content. Once in a while, you'll want to sync with everyone else, in which case go to the original directory, sync using the other version control system, and type: diff --git a/grandmaster.txt b/grandmaster.txt index a2e0e92..dbcfc63 100644 --- a/grandmaster.txt +++ b/grandmaster.txt @@ -6,13 +6,13 @@ This pretentiously named page is my dumping ground for uncategorized Git tricks. For my projects, Git tracks exactly the files I'd like to archive and release to users. So to create a tarball of the source code, I run: - $ git-archive --format==tar --prefix==proj-1.2.3/ HEAD + $ git archive --format==tar --prefix==proj-1.2.3/ HEAD === Changelog Generation === 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 - $ git-log > ChangeLog + $ git log > ChangeLog === Git Over SSH, HTTP === @@ -20,7 +20,7 @@ Suppose you have ssh access to your web server, but it does not have Git install Create a repository in your web directory: - $ GIT_DIR==proj.git git-init + $ GIT_DIR==proj.git git init and in the "proj.git" directory, run @@ -39,17 +39,17 @@ and people can get your project via Telling Git when you've added, deleted and renamed files gets tedious. Instead, try: - $ git-ls-files -d -m -o -z | xargs -0 git-update-index --add --remove + $ git ls-files -d -m -o -z | xargs -0 git update-index --add --remove and Git will look at the files in the current directory and work everything out for itself. The *-z* and *-0* options prevent ill side-effects from filenames containing strange characters. You might want it to ignore particular files: - $ git-ls-files -d -m -o -z -x *.tmp | xargs -0 git-update-index --add --remove + $ git ls-files -d -m -o -z -x *.tmp | xargs -0 git update-index --add --remove If you have a big list of directories and files that should never be version controlled, type them into a separate file named ".gitignore" and run: - $ git-ls-files -d -m -o -z -X .gitignore | xargs -0 git-update-index --add --remove + $ git ls-files -d -m -o -z -X .gitignore | xargs -0 git update-index --add --remove You can also exclude files on a per-directory basis. See the help page. @@ -82,9 +82,9 @@ Then: - Replace "pick" with "edit" to mark a commit for amending. - Replace "pick" with "squash" to merge a commit with the previous one. -Next run *git-commit --amend* if you marked a commit for editing. Otherwise, run: +Next run *git commit --amend* if you marked a commit for editing. Otherwise, run: - $ git-rebase --continue + $ git rebase --continue Again, only do this if no one else has a clone of your tree. @@ -95,7 +95,7 @@ then you sync with the official tree with a merge. This cycle repeats itself a f 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. -This is a job for *git-rebase* as described above. In many cases you can use +This is a job for *git rebase* as described above. In many cases you can use the *--onto* flag and avoid interaction. 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! @@ -115,7 +115,7 @@ The HEAD tag is like a cursor that normally points at the latest commit, advanci $ git reset HEAD~3 -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. +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. But how can you go back to the future? The past commits do not know anything of the future. @@ -131,13 +131,13 @@ But suppose you never took it down? Don't worry, for commands like these, Git sa 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. -It's hard to lose Git commits permanently, even after deleting branches. As long as you never run git-gc, your commits are preserved forever and can be restored at any time. +It's hard to lose Git commits permanently, even after deleting branches. As long as you never run git gc, your commits are preserved forever and can be restored at any time. 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. 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. -Eventually, you may want to run git-gc to recover space. Be aware that doing so prevents you from recovering lost HEADs. +Eventually, you may want to run git gc to recover space. Be aware that doing so prevents you from recovering lost HEADs. === Building On Git === @@ -154,11 +154,11 @@ commands: Another is to print the current branch in the prompt, or window title. Invoking - $ git-symbolic-ref HEAD + $ git symbolic-ref HEAD shows the current branch name. In practice, you most likely want to remove the "refs/heads/" and ignore errors: - $ git-symbolic-ref HEAD 2> /dev/null | cut -b 12- + $ git symbolic-ref HEAD 2> /dev/null | cut -b 12- See http://git.or.cz/[the Git homepage] for more examples. diff --git a/secrets.txt b/secrets.txt index bc22d45..6f11985 100644 --- a/secrets.txt +++ b/secrets.txt @@ -32,7 +32,7 @@ I've ignored details such as file permissions and signatures. See the link:.[ref === Intelligence === -How does Git know you renamed a file, even though you never mentioned the fact explicitly? Sure, you may have run *git-mv*, but that is exactly the same as a *git-rm* followed by a *git-add*. +How does Git know you renamed a file, even though you never mentioned the fact explicitly? Sure, you may have run *git mv*, but that is exactly the same as a *git rm* followed by a *git add*. Git heuristically ferrets out renames and copies between successive versions. In fact, it can detect chunks of code being moved or copied around between files! Though it cannot cover all cases, it does a decent job, and this feature is always improving. If it does not seem to be working for you, consider upgrading. @@ -55,7 +55,7 @@ Git on Window can be cumbersome. It works with Cygwin installed, though is slowe If your project is very large and contains many unrelated files that are constantly being changed, Git may be disadvantaged more than other systems because single files are not tracked. Git tracks changes to the whole project, which is usually beneficial. -A solution is to break up your project into pieces, each consisting of related files. Use *git-submodule* if you still want to keep everything in a single repository. +A solution is to break up your project into pieces, each consisting of related files. Use *git submodule* if you still want to keep everything in a single repository. ==== Volatile Projects ==== @@ -79,8 +79,8 @@ Actually, every clone could maintain such a counter, but this would probably not ==== Automatic Compression ==== -To save space, *git-gc* should be run once in a while. Some complain because this must be done manually. But it is trivial to write scripts to run this program automatically. Ideally it should occur when during periods of little activity. +To save space, *git gc* should be run once in a while. Some complain because this must be done manually. But it is trivial to write scripts to run this program automatically. Ideally it should occur when during periods of little activity. For working repositories, not running the git garbage collector at all may be wiser, because you can restore accidentally deleted commits. -In this sense, the fact that you choose when garbage collection occurs is a blessing. On busy, official repositories, you can setup a script to frequently run *git-gc* while on your own machine, you might choose never to run it (so you can walways undo a mistake), and perhaps opt for an occasional *git-repack* instead. +In this sense, the fact that you choose when garbage collection occurs is a blessing. On busy, official repositories, you can setup a script to frequently run *git gc* while on your own machine, you might choose never to run it (so you can walways undo a mistake), and perhaps opt for an occasional *git repack* instead. -- 2.11.4.GIT