введение в 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