Путеводитель по Руководству Linux

  User  |  Syst  |  Libr  |  Device  |  Files  |  Other  |  Admin  |  Head  |



   gittutorial    ( 7 )

введение в Git (A tutorial introduction to Git)

EXPLORING HISTORY

Git history is represented as a series of interrelated commits. We have already seen that the git log command can list those commits. Note that first line of each git log entry also gives a name for the commit:

$ git log commit c82a22c39cbc32576f64f5c6b3f24b99ea8149c7 Author: Junio C Hamano <junkio@cox.net> Date: Tue May 16 17:18:22 2006 -0700

merge-base: Clarify the comments on post processing.

We can give this name to git show to see the details about this commit.

$ git show c82a22c39cbc32576f64f5c6b3f24b99ea8149c7

But there are other ways to refer to commits. You can use any initial part of the name that is long enough to uniquely identify the commit:

$ git show c82a22c39c # the first few characters of the name are # usually enough $ git show HEAD # the tip of the current branch $ git show experimental # the tip of the "experimental" branch

Every commit usually has one "parent" commit which points to the previous state of the project:

$ git show HEAD^ # to see the parent of HEAD $ git show HEAD^^ # to see the grandparent of HEAD $ git show HEAD~4 # to see the great-great grandparent of HEAD

Note that merge commits may have more than one parent:

$ git show HEAD^1 # show the first parent of HEAD (same as HEAD^) $ git show HEAD^2 # show the second parent of HEAD

You can also give commits names of your own; after running

$ git tag v2.5 1b2e1d63ff

you can refer to 1b2e1d63ff by the name "v2.5". If you intend to share this name with other people (for example, to identify a release version), you should create a "tag" object, and perhaps sign it; see git-tag(1) for details.

Any Git command that needs to know a commit can take any of these names. For example:

$ git diff v2.5 HEAD # compare the current HEAD to v2.5 $ git branch stable v2.5 # start a new branch named "stable" based # at v2.5 $ git reset --hard HEAD^ # reset your current branch and working # directory to its state at HEAD^

Be careful with that last command: in addition to losing any changes in the working directory, it will also remove all later commits from this branch. If this branch is the only branch containing those commits, they will be lost. Also, don't use git reset on a publicly-visible branch that other developers pull from, as it will force needless merges on other developers to clean up the history. If you need to undo changes that you have pushed, use git revert instead.

The git grep command can search for strings in any version of your project, so

$ git grep "hello" v2.5

searches for all occurrences of "hello" in v2.5.

If you leave out the commit name, git grep will search any of the files it manages in your current directory. So

$ git grep "hello"

is a quick way to search just the files that are tracked by Git.

Many Git commands also take sets of commits, which can be specified in a number of ways. Here are some examples with git log:

$ git log v2.5..v2.6 # commits between v2.5 and v2.6 $ git log v2.5.. # commits since v2.5 $ git log --since="2 weeks ago" # commits from the last 2 weeks $ git log v2.5.. Makefile # commits since v2.5 which modify # Makefile

You can also give git log a "range" of commits where the first is not necessarily an ancestor of the second; for example, if the tips of the branches "stable" and "master" diverged from a common commit some time ago, then

$ git log stable..master

will list commits made in the master branch but not in the stable branch, while

$ git log master..stable

will show the list of commits made on the stable branch but not the master branch.

The git log command has a weakness: it must present commits in a list. When the history has lines of development that diverged and then merged back together, the order in which git log presents those commits is meaningless.

Most projects with multiple contributors (such as the Linux kernel, or Git itself) have frequent merges, and gitk does a better job of visualizing their history. For example,

$ gitk --since="2 weeks ago" drivers/

allows you to browse any commits from the last 2 weeks of commits that modified files under the "drivers" directory. (Note: you can adjust gitk's fonts by holding down the control key while pressing "-" or "+".)

Finally, most commands that take filenames will optionally allow you to precede any filename by a commit, to specify a particular version of the file:

$ git diff v2.5:Makefile HEAD:Makefile.in

You can also use git show to see any such file:

$ git show v2.5:Makefile