From db3ff41ed7251657b41e183d375cc6cf2d97a325 Mon Sep 17 00:00:00 2001 From: Ben Lynn Date: Fri, 7 Sep 2007 18:25:12 -0700 Subject: [PATCH] Wrote "Don't Lose Your HEAD" Edits: branching, heuristics, other minor ones --- branch.txt | 19 ++++++++++--------- grandmaster.txt | 24 ++++++++++++++++++++++-- secrets.txt | 2 +- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/branch.txt b/branch.txt index 9196737..f84086b 100644 --- a/branch.txt +++ b/branch.txt @@ -1,6 +1,6 @@ -= Branch Magic = += Branch Wizardry = -Now that you've mastered some simple Git sleights, it's time to learn some real crowd-pleasers. +Instant branching and merging are the most lethal of Git's killer features. *Problem*: External factors inevitably necessitate context switching. A severe bug manifests in the released version suddenly without warning, and must be fixed as soon as possible at all costs. The deadline for a certain feature is imminent. The guy who wrote a certain function is about to leave, so you should drop what you are doing and get him to help you understand it. @@ -8,12 +8,11 @@ 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*. With this magic word, the files in your directory instantly 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. +*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. == The Boss Key == -Ever play one of those games where you could hit a special key combination at -any time, and the screen would instantly display a spreadsheet or something? So if the boss walked in the office while you were playing the game you could quickly hide this fact? +Ever play one of those games where at the push of a button ("the boss key"), the screen would instantly display a spreadsheet or something? So if the boss walked in the office while you were playing the game you could quickly hide this fact? In some directory: @@ -38,8 +37,6 @@ and hey presto! The text file is restored. And if the boss decides to snoop arou You can switch between the two versions of the file as much as you like, and commit to each independently. -You may have real applications for this trick. Perhaps you have a program that reads data from a certain directory, and every now and then you'd like to switch the data back and forth without reconfiguring the program. - == Dirty Work == Say you're working on some feature, and for some reason, you need to go back to an old version and temporarily need to put in a few prints statements to see how something works. Then: @@ -61,9 +58,13 @@ before switching back to the master branch. Whenever you want to return to the d $ git checkout dirty +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*. + == Quick Fixes == -This time, say you're in the middle of something and you are required to drop everything and work on fixing a bug that's just been reported: +You're in the middle of something when you are told to drop everything and fix a newly discovered bug: $ git commit -a $ git checkout -b fixes SHA1_HASH @@ -125,7 +126,7 @@ The branch command can also do other operations with branches. See *git help bra Several Linux window managers allow you to have multiple desktops, which means you can instantly view a different state of the desktop. Git branching is like multiple desktops for your working directory. Continuing this analogy, Git cloning is like attaching another monitor on which you can open more windows. -Perhaps a better example is the famous [[http://www.gnu.org/software/screen/][*screen*]] utility. This gem allows you to create, destroy and switch between multiple terminal sessions in the same terminal. Instead of opening new terminals (clone), you can use the same one if you run *screen* (branch). In fact, you can do a lot more with *screen* but that's a topic for another day. +Perhaps a better example is the [[http://www.gnu.org/software/screen/][*screen*]] utility. This gem allows you to create, destroy and switch between multiple terminal sessions in the same terminal. Instead of opening new terminals (clone), you can use the same one if you run *screen* (branch). In fact, you can do a lot more with *screen* but that's a topic for another day. Web browsers like [[http://www.mozilla.com/][Mozilla Firefox]] allow you to open multitple tabs and multiple windows which are analogous to branching and cloning in Git. Being able to do both easily makes for a better user experience. diff --git a/grandmaster.txt b/grandmaster.txt index 2464e1a..3aa5e64 100644 --- a/grandmaster.txt +++ b/grandmaster.txt @@ -47,9 +47,11 @@ You might want it to ignore particular files: $ 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 "ignore" and run: +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 ignore | 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. == I Stand Corrected == @@ -59,6 +61,24 @@ Did you just commit, but wish you had typed a different message? Realized you fo can help you out. +== Don't Lose Your HEAD == + +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: + + $ 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. + +But how can you go back to the future? The past commits do not know anything of the future. + +If you have the SHA1 of the original HEAD then: + + $ git reset SHA1 + +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: + + $ git reset ORIG_HEAD + == Building On Git == 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. diff --git a/secrets.txt b/secrets.txt index 55e083f..165f2cb 100644 --- a/secrets.txt +++ b/secrets.txt @@ -34,7 +34,7 @@ I've ignored details such as file permissions and signatures. See the [[.][refer 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. Though it cannot cover all cases, it does a decent job, and this feature is always improving. +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. == Bare Repositories == -- 2.11.4.GIT