From 3bad93ae6e35200f77549443103ddcc0fd2fb6d5 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 27 Sep 2007 21:58:28 -0700 Subject: [PATCH] Port section 2.4 (a tour through history) from mercurial to git --- tour.mdwn | 369 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 214 insertions(+), 155 deletions(-) diff --git a/tour.mdwn b/tour.mdwn index d697f90..6a43df9 100644 --- a/tour.mdwn +++ b/tour.mdwn @@ -219,59 +219,64 @@ project at a particular point in history. ### 2.4 A tour through history One of the first things we might want to do with a new, unfamiliar -repository is understand its history. The “hg log” command gives us a +repository is understand its history. The “git log” command gives us a view of history. - $ hg log - changeset: 4:b57f9a090b62 - tag: tip - user: Bryan O'Sullivan - date: Tue Sep 06 15:43:07 2005 -0700 - summary: Trim comments. + $ git log + commit a1a0e8b392b17caf50325498df54802fe3c03710 + Author: Bryan O'Sullivan + Date: Tue Sep 6 15:43:07 2005 -0700 - changeset: 3:ff5d7b70a2a9 - user: Bryan O'Sullivan - date: Tue Sep 06 13:15:58 2005 -0700 - summary: Get make to generate the final binary from a .o file. + Trim comments. - changeset: 2:057d3c2d823c - user: Bryan O'Sullivan - date: Tue Sep 06 13:15:43 2005 -0700 - summary: Introduce a typo into hello.c. + commit 72d4f10e4a27dbb09ace1503c20dbac1912ee451 + Author: Bryan O'Sullivan + Date: Tue Sep 6 13:15:58 2005 -0700 + + Get make to generate the final binary from a .o file. + + commit 13ed136b983a9c439eddeea8a1c2076cffbb685f + Author: Bryan O'Sullivan + Date: Tue Sep 6 13:15:43 2005 -0700 + + Introduce a typo into hello.c. + + commit 0a633bf58b45fcf1a8299d3c82cd1fd26d3f48f2 + Author: Bryan O'Sullivan + Date: Fri Aug 26 01:21:28 2005 -0700 - changeset: 1:82e55d328c8c - user: mpm@selenic.com - date: Fri Aug 26 01:21:28 2005 -0700 - summary: Create a makefile + Create a makefile - changeset: 0:0a04b987be5a - user: mpm@selenic.com - date: Fri Aug 26 01:20:50 2005 -0700 - summary: Create a standard "hello, world" program + commit db7117a9dd9a6e57e8632ea5848e1101eee0fbde + Author: Bryan O'Sullivan + Date: Fri Aug 26 01:20:50 2005 -0700 + Create a standard "hello, world" program By default, this command prints a brief paragraph of output for each change to the project that was recorded. In git terminology, we -call each of these recorded events a changeset, because it can contain -a record of changes to several files. - -The fields in a record of output from “hg log” are as follows. - - * changeset This field has the format of a number, followed by a - colon, followed by a hexadecimal string. These are identifiers for - the changeset. There are two identifiers because the number is - shorter and easier to type than the hex string. - * user The identity of the person who created the changeset. This is - a free-form field, but it most often contains a person’s name and - email address. - * date The date and time on which the changeset was created, and the - timezone in which it was created. (The date and time are local to - that timezone; they display what time and date it was for the - person who created the changeset.) - * summary The first line of the text message that the creator of the - changeset entered to describe the changeset. - -The default output printed by “hg log” is purely a summary; it is +call each of these recorded events a commit. + +The fields in a record of output from “git log” are as follows. + + * commit This field consists of a string of 40 hexadecimal characters. + This is a unique identifier for referring to particular commits. + * Author The identity of the person who authored the commit. This + field consist of two sub-fields for the user's name and email + address, (or at least an email-like idenitifer). Note that git + stores a separate "Committer" field for the person who commited + the change, (since often an author will email a change to a + maintainer that commits it). The "git log" command doesn't display + the Committer, but other git tools do. + * Date The date and time on which the commit was authored, (again + stored separately from the date the change was committed). + timezone in which it was created. (The date and time are displayed + in the timezone of the person who created the commit.) + * commit message The text message that the creator of the commit + entered to describe the commit, (generally a one-line summary + followed by more supporting text). + +The default output printed by “git log” is purely a summary; it is missing a lot of detail. Figure [2.1][8] provides a graphical representation of the history of @@ -288,142 +293,196 @@ Graphical history of the hello repository * * * -#### 2.4.1 Changesets, revisions, and talking to other people +#### 2.4.1 Commits, revisions, and talking to other people As English is a notoriously sloppy language, and computer science has a hallowed history of terminological confusion (why use one term when four will do?), revision control has a variety of words and phrases -that mean the same thing. If you are talking about Mercurial history -with other people, you will find that the word “changeset” is often -compressed to “change” or (when written) “cset”, and sometimes a -changeset is referred to as a “revision” or a “rev”. - -While it doesn’t matter what word you use to refer to the concept of -“a changeset”, the identifier that you use to refer to “a specific -changeset” is of great importance. Recall that the changeset field in -the output from “hg log” identifies a changeset using both a number -and a hexadecimal string. - - * The revision number is only valid in that repository, - * while the hex string is the permanent, unchanging identifier that - will always identify that exact changeset in every copy of the - repository. - -This distinction is important. If you send someone an email talking -about “revision 33”, there’s a high likelihood that their revision 33 -will not be the same as yours. The reason for this is that a revision -number depends on the order in which changes arrived in a repository, -and there is no guarantee that the same changes will happen in the -same order in different repositories. Three changes a,b,c can easily -appear in one repository as 0,1,2, while in another as 1,0,2. - -Mercurial uses revision numbers purely as a convenient shorthand. If -you need to discuss a changeset with someone, or make a record of a -changeset for some other reason (for example, in a bug report), use -the hexadecimal identifier. - -#### 2.4.2 Viewing specific revisions - -To narrow the output of “hg log” down to a single revision, use the -r -(or --rev) option. You can use either a revision number or a long-form -changeset identifier, and you can provide as many revisions as you -want. - - $ hg log -r 3 - changeset: 3:ff5d7b70a2a9 - user: Bryan O'Sullivan - date: Tue Sep 06 13:15:58 2005 -0700 - summary: Get make to generate the final binary from a .o file. +that mean the same thing. If you are talking about git history +with other people, you will find that what we have called a “commit” +is often called a "revision". In other systems, a similar notion +is referred to as a "changeset". You might even see abbreviations of +these terms such as "rev", "change", or even "cset". + +While it may not matter much what word you use to refer to the concept +of “a commit”, it's important to know how to name “a specific +commit”. We have already seen one means of referring to a particular +commit, the 40-character hexadecimal string shown by "git log". These +commit identifiers are powerful because they are permanent, unique +identifiers that always identify the same commit in any copy of a +repository. If two users are examining a working directory associated +with the same commit identifier, then those two users have precisely +the same contents in all files, and exactly the same history leading +to that commit. + +So there are places where it is often important to archive the +complete commit identifier, (perhaps in bug-tracking systems to +indicate a specific commit that fixes a bug, for example). But often, +in more casual settings, it's more convenient to use abbreviated +commit identifiers. Git accept any unique prefix of a commit +identifier, (and for reasonably-sized project the first 8 or 10 +characters are almost always unique). + +And unlike the permanent commit identifiers, git also provides +transient means of identifying commits. In fact, in day-to-day use of +git, you will probably use these names more than commit +identifiers. One example is branch names, (such as the default +"master" branch in any git repository), or any project-specific branch +names such as "stable", "experimental", or "crazy-insane-changes". Git +also provides a special name "HEAD" which always refers to the current +branch. + +#### 2.4.2 Naming related commits + +Git offers simple ways to name revisions that are related to +particular revisions in the history. One syntax is the ~ suffix which +refers to the parent of a commit, or if followed by a number, to the +Nth parent. For example, since "HEAD" refers to the most recent commit +in the current branch, "HEAD~", refers to the previous commit, and +"HEAD~2" refers to two commits back in the history. + +Another useful syntax is .. which can be used to specify a range of +commits. So "origin..master" specifies everything that has been +committed to master since it derived from origin. + +#### 2.4.3 Viewing specific revisions + +You can use "git log" to explore the range syntax just introduced. For +example, to see a list of the most recent 3 revisions you can use +"HEAD~3..", (the destination of the range is implicitly HEAD in this +case): + + $ git log HEAD~3.. + commit a1a0e8b392b17caf50325498df54802fe3c03710 + Author: Bryan O'Sullivan + Date: Tue Sep 6 15:43:07 2005 -0700 - $ hg log -r ff5d7b70a2a9 - changeset: 3:ff5d7b70a2a9 - user: Bryan O'Sullivan - date: Tue Sep 06 13:15:58 2005 -0700 - summary: Get make to generate the final binary from a .o file. + Trim comments. - $ hg log -r 1 -r 4 - changeset: 1:82e55d328c8c - user: mpm@selenic.com - date: Fri Aug 26 01:21:28 2005 -0700 - summary: Create a makefile + commit 72d4f10e4a27dbb09ace1503c20dbac1912ee451 + Author: Bryan O'Sullivan + Date: Tue Sep 6 13:15:58 2005 -0700 - changeset: 4:b57f9a090b62 - tag: tip - user: Bryan O'Sullivan - date: Tue Sep 06 15:43:07 2005 -0700 - summary: Trim comments. + Get make to generate the final binary from a .o file. + commit 13ed136b983a9c439eddeea8a1c2076cffbb685f + Author: Bryan O'Sullivan + Date: Tue Sep 6 13:15:43 2005 -0700 + + Introduce a typo into hello.c. -If you want to see the history of several revisions without having to -list each one, you can use range notation; this lets you express the -idea “I want all revisions between a and b, inclusive”. +#### 2.4.4 Other log filters - $ hg log -r 2:4 - changeset: 2:057d3c2d823c - user: Bryan O'Sullivan - date: Tue Sep 06 13:15:43 2005 -0700 - summary: Introduce a typo into hello.c. +Besides filtering by commit identifiers, git allows you to easily +filter the log output according to which files (or directories) are +modified by listing them after "--" wihch is necessary to distinguish +commit names from file names: + + $ git log -- Makefile + commit 72d4f10e4a27dbb09ace1503c20dbac1912ee451 + Author: Bryan O'Sullivan + Date: Tue Sep 6 13:15:58 2005 -0700 - changeset: 3:ff5d7b70a2a9 - user: Bryan O'Sullivan - date: Tue Sep 06 13:15:58 2005 -0700 - summary: Get make to generate the final binary from a .o file. + Get make to generate the final binary from a .o file. - changeset: 4:b57f9a090b62 - tag: tip - user: Bryan O'Sullivan - date: Tue Sep 06 15:43:07 2005 -0700 - summary: Trim comments. + commit 0a633bf58b45fcf1a8299d3c82cd1fd26d3f48f2 + Author: Bryan O'Sullivan + Date: Fri Aug 26 01:21:28 2005 -0700 + Create a makefile + +And "git log" can also filter based on the dates at which commits were +created: -Mercurial also honours the order in which you specify revisions, so -“hg log -r 2:4” prints 2,3,4 while “hg log -r 4:2” prints 4,3,2. + $ git log --since="2 weeks ago" --until="yesterday" + +Another useful option is --max-count which, unsurprisingly, limits the +maximum number of commits to be displayed. #### 2.4.3 More detailed information -While the summary information printed by “hg log” is useful if you -already know what you’re looking for, you may need to see a complete -description of the change, or a list of the files changed, if you’re -trying to decide whether a changeset is the one you’re looking -for. The “hg log” command’s -v (or --verbose) option gives you this -extra detail. +While the default information printed by “git log” is useful if you +already know what you’re looking for, you may need to see more details +of the change, such as the "diffstat" information with --stat: - $ hg log -v -r 3 - changeset: 3:ff5d7b70a2a9 - user: Bryan O'Sullivan - date: Tue Sep 06 13:15:58 2005 -0700 - files: Makefile - description: - Get make to generate the final binary from a .o file. + $ git log --stat --max-count=3 + commit a1a0e8b392b17caf50325498df54802fe3c03710 + Author: Bryan O'Sullivan + Date: Tue Sep 6 15:43:07 2005 -0700 + Trim comments. - -If you want to see both the description and content of a change, add -the -p (or --patch) option. This displays the content of a change as a -unified diff (if you’ve never seen a unified diff before, see -section [12.4][10] for an overview). - - $ hg log -v -p -r 2 - changeset: 2:057d3c2d823c - user: Bryan O'Sullivan - date: Tue Sep 06 13:15:43 2005 -0700 - files: hello.c - description: - Introduce a typo into hello.c. + hello.c | 8 ++------ + 1 files changed, 2 insertions(+), 6 deletions(-) + commit 72d4f10e4a27dbb09ace1503c20dbac1912ee451 + Author: Bryan O'Sullivan + Date: Tue Sep 6 13:15:58 2005 -0700 - diff -r 82e55d328c8c -r 057d3c2d823c hello.c - --- a/hello.c Fri Aug 26 01:21:28 2005 -0700 - +++ b/hello.c Tue Sep 06 13:15:43 2005 -0700 - @@ -11,6 +11,6 @@ + Get make to generate the final binary from a .o file. - int main(int argc, char ⋆⋆argv) - { - - printf("hello, world!∖n"); - + printf("hello, world!∖"); - return 0; - } + Makefile | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + + commit 13ed136b983a9c439eddeea8a1c2076cffbb685f + Author: Bryan O'Sullivan + Date: Tue Sep 6 13:15:43 2005 -0700 + + Introduce a typo into hello.c. + + hello.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +Or perhaps you'd like to see the actual patch content of each change, +which you can get with -p. That commit with the word typo in its name +looks suspicous, so let's tak a closer look. Remember that we can name +it as master~3, HEAD~3, or any prefix of its commit identifier, (such +as 13ed136b): + + $ git log -p --max-count=1 13ed136b + commit 13ed136b983a9c439eddeea8a1c2076cffbb685f + Author: Bryan O'Sullivan + Date: Tue Sep 6 13:15:43 2005 -0700 + + Introduce a typo into hello.c. + + diff --git a/hello.c b/hello.c + index ed55ec0..80b260c 100644 + --- a/hello.c + +++ b/hello.c + @@ -11,6 +11,6 @@ + + int main(int argc, char **argv) + { + - printf("hello, world!\n"); + + printf("hello, world!\"); + return 0; + } + +Of course, wanting to see all this information for a single commit is +such a common operation that it's given its own name in git, "git +show". So "git show 13ed136b" is a much easier way to get exactly the +same output: + + $ git show 13ed136b + commit 13ed136b983a9c439eddeea8a1c2076cffbb685f + Author: Bryan O'Sullivan + Date: Tue Sep 6 13:15:43 2005 -0700 + + Introduce a typo into hello.c. + diff --git a/hello.c b/hello.c + index ed55ec0..80b260c 100644 + --- a/hello.c + +++ b/hello.c + @@ -11,6 +11,6 @@ + + int main(int argc, char **argv) + { + - printf("hello, world!\n"); + + printf("hello, world!\"); + return 0; + } ### 2.5 All about command options -- 2.43.0