Git入门


Git入门(1.5.1及以上)

A tutorial introduction to git (for version 1.5.1 or newer)

This tutorial explains how to import a new project into git, make changes to it, and share changes with other developers.

[介绍了如何导入新项目,如何修改,如何分享这些改动。]

If you are instead primarily interested in using git to fetch a project, for example, to test the latest version, you may prefer to start with the first two chapters of The Git User's Manual.

[如果你的兴趣不在此处,而是利用 git 测试某个项目的最新版本,可以去看 The Git User's Manual 头两章]

First, note that you can get documentation for a command such as "git diff" with:

[首先,注意各种命令的帮助文档使用 man 命令,如 man git-diff]

$ man git-diff

It is a good idea to introduce yourself to git with your name and public email address before doing any operation. The easiest way to do so is:

[建议:首先向 git 介绍自己,告诉它你的名字和邮箱,如下:]

$ git config --global user.name "Your Name Comes Here"
$ git config --global user.email you@yourdomain.example.com

Importing a new project [导入新项目]

Assume you have a tarball project.tar.gz with your initial work. You can place it under git revision control as follows.

[ 假设你从一个 project.tar.gz 文件包开始你的工资,便可以将其放入git版本控制中,如下:]
$ tar xzf project.tar.gz
$ cd project
$ git init

Git will reply [Git 会提示:]

Initialized empty Git repository in .git/ [一个空的 Git 仓库初始化完成,存于./git 文件夹]

You've now initialized the working directory—you may notice a new directory created, named ".git".

Next, tell git to take a snapshot of the contents of all files under the current directory (note the .), with git-add(1):

[你现在即已经初始化好了工作文件夹---你会看到系统创建了一个新文件夹 “.git”,然后就可以使用下面的命令 git-add(1) 让 git 抓取当前文件夹中所有文件的快照,注意命令中的表示当前文件夹的 “.”号]

$ git add .

This snapshot is now stored in a temporary staging area which git calls the "index". You can permanently store the contents of the index in the repository with git-commit(1):

[现在文件的快照已经存入了一个临时性、阶段性区域,git 把它叫做 “索引”。你可以利用 git-commit(1) 命令将索引内容永久性地存入仓库中,如下:]

$ git commit

This will prompt you for a commit message. You've now stored the first version of your project in git.

[这个命令将提示你输入提交(commit)信息,现在我们已经在 git 中保存了项目的第一个版本。]

Making changes [修改项目]

Modify some files, then add their updated contents to the index:

[修改某些文件,然后将更新内容加入到索引中,如下:]

$ git add file1 file2 file3

You are now ready to commit. You can see what is about to be committed using git-diff(1) with the —cached option:

[修改完后,我们应该是处于准备提交阶段。之前,你可以使用 git-diff(1) 加上 --cached 选项来查看哪些内容会被提交,如下:]

$ git diff --cached

(Without —cached, git-diff(1) will show you any changes that you've made but not yet added to the index.) You can also get a brief summary of the situation with git-status(1):

[如果不使用 --cached,git-diff(1) 将显示那些修改了但还没有加入到索引中的变化。你可以使用 git-status(1) 命令查看修改摘要。]

$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: file1
# modified: file2
# modified: file3
#

If you need to make any further adjustments, do so now, and then add any newly modified content to the index. Finally, commit your changes with:

[如果你需要做出进一步修改,那么在修改后,还是要将修改的内容加入索引中,最后提交变化,如下:]

$ git commit

This will again prompt you for a message describing the change, and then record a new version of the project.

[该命令将再次提示你输入描述信息,记录新版本信息。]

Alternatively, instead of running git add beforehand, you can use

[另外,在运行加入之前,你可以使用以下命令:]

$ git commit -a

which will automatically notice any modified (but not new) files, add them to the index, and commit, all in one step.

[运行后,git 将自动注意除了新增加文件外的任何修改,并加入索引,然后提示我们提交修改,一步完成。]

A note on commit messages: Though not required, it's a good idea to begin the commit message with a single short (less than 50 character) line summarizing the change, followed by a blank line and then a more thorough description. Tools that turn commits into email, for example, use the first line on the Subject: line and the rest of the commit in the body.

[关于提交信息的提示:虽然不是必需,但用简短的语句总结做所的修改还是很好的习惯,并且可以空一行进行比较详细的描述。这对于可以将变化使用email提交的工具来说也是个好处,比如使用第一行作为主题,剩余部分作为邮件主题内容。]

Git tracks content not files

[Git 跟踪的是内容而不是文件]

Many revision control systems provide an "add" command that tells the system to start tracking changes to a new file. Git's "add" command does something simpler and more powerful: git add is used both for new and newly modified files, and in both cases it takes a snapshot of the given files and stages that content in the index, ready for inclusion in the next commit.

[很多版本控制系统提供“add”命令,以此告诉系统开始跟踪某个新文件的变化。然后 Git 的 “add”命令使之变得更简单并更强大:首先,git 的 add 命令既用于新文件也同时用于新修改的文件,并且在这两种情况下它都能获取给定文件的快照,同时将其内容升级入索引中,并为下一次提交做好准备工作。]

Viewing project history [查看项目历史]

At any point you can view the history of your changes using

[我们可以随时随地通过如下命令查看项目修改历史]

$ git log

If you also want to see complete diffs at each step, use

[如果你想了解所有阶段的所有差异,可以使用下面命令]

$ git log -p

Often the overview of the change is useful to get a feel of each step

[通常,修改汇总的显示对把握全局是非常有用的,如下命令]

$ git log --stat --summary

Managing branches [管理分支]

A single git repository can maintain multiple branches of development. To create a new branch named "experimental", use

[单个 git 仓库能够维护若干个开发分支,例如创建名为 “experimental”的分支,可以使用如下命令:]

$ git branch experimental

If you now run [如果运行....]

$ git branch

you'll get a list of all existing branches: [我们将会得到所有现有分支的列表,如下:]

  experimental
* master

The "experimental" branch is the one you just created, and the "master" branch is a default branch that was created for you automatically. The asterisk marks the branch you are currently on; type

[其中,“experimental”分支是我们刚刚建立的,另外的“master”分支则是系统默认分支,为使用者自动创建。星号* 则表示目前我们正编辑的分支。然后运行如下命令:]

$ git checkout experimental

to switch to the experimental branch. Now edit a file, commit the change, and switch back to the master branch:

[该命令即让当前分支转为“experimental”。现在我们先编辑一个文件,然后提交修改,并转回到 master 分支,如下操作:]

(edit file)
$ git commit -a
$ git checkout master

Check that the change you made is no longer visible, since it was made on the experimental branch and you're back on the master branch.

[我们会发现,转回 master 后,之前在 experimental 中所做的修改已经不再可见。]

You can make a different change on the master branch:

[现在,我们再尝试在 master 中做不同的修改,如下:]

(edit file)
$ git commit -a

at this point the two branches have diverged, with different changes made in each. To merge the changes made in experimental into master, run

[此时,两个分支是分离的,并且各自包含不同的修改,如果想将 experimental 中所做的修改合并进 master 中,我们可以运行....]

$ git merge experimental

If the changes don't conflict, you're done. If there are conflicts, markers will be left in the problematic files showing the conflict;

[如果,以上修改不发生冲突的话,我们就齐活了。如果存有冲突,星号标记将出现在有问题的文件左边,向我们突出显示出冲突之处。]

$ git diff

will show this. Once you've edited the files to resolve the conflicts,

[git diff 命令可以列出这些冲突。一旦我们通过再次编辑文件解决了这些冲突...]

$ git commit -a

will commit the result of the merge. Finally, [commit 命令将提交合并后的结果,最终运行...]

$ gitk

will show a nice graphical representation of the resulting history.

[该命令将用一幅优美的图展示出问题发生、解决的过程。]

At this point you could delete the experimental branch with

[此时,你可以删除 experimental 分支,使用命令:]

$ git branch -d experimental

This command ensures that the changes in the experimental branch are already in the current branch.

[该命令将确保 experimental 中的修改已经反映在当前分支中。]

If you develop on a branch crazy-idea, then regret it, you can always delete the branch with

[我们还可以使用 -D 参数随时删除分支,不管它已经合并与否,如下:]

$ git branch -D crazy-idea

Branches are cheap and easy, so this is a good way to try something out.

[记住,分支不值钱,但可以发现它是试探性开发中的一个很好的辅助工具。]

Using git for collaboration [用 Git 进行合作开发]

Suppose that Alice has started a new project with a git repository in /home/alice/project, and that Bob, who has a home directory on the same machine, wants to contribute.

[假设 Alice 使用 git 仓库创建了一个新项目,文件目录为 /home/alice/project,而同时 Bob 在同一台计算机上也有自己的home文件夹,并想为该新项目作些贡献。]

Bob begins with: [ Bob 可以如下开始他的工作:]

$ git clone /home/alice/project myrepo

This creates a new directory "myrepo" containing a clone of Alice's repository. The clone is on an equal footing with the original project, possessing its own copy of the original project's history.

[以上命令创建了一个新的文件夹 “myrepo”这个文件夹包含 Alice 项目仓库的一个克隆版本。该克隆版与原始项目几乎一样,同样拥有原项目的历史记录。]

Bob then makes some changes and commits them: [ Bob 然后对项目进行了修改并提交上去:]

(edit files)
$ git commit -a
(repeat as necessary)

When he's ready, he tells Alice to pull changes from the repository at /home/bob/myrepo. She does this with:

[当 Bob 修改完成后,他便告诉 Alice 可以通过 /home/bob/myrepo 仓库中抽取他的修改,Alice 随后运行如下命令:]

$ cd /home/alice/project
$ git pull /home/bob/myrepo master

This merges the changes from Bob's "master" branch into Alice's current branch. If Alice has made her own changes in the meantime, then she may need to manually fix any conflicts. (Note that the "master" argument in the above command is actually unnecessary, as it is the default.)

[以上命令完成将 Bob 的 master 分支合并入 Alice 当前分支中的任务。如果 Alice 同时还进行了自己的修改,那么她此时需要手工修改两个分支中的所有冲突。注意:以上命令中的 “master”参数实际上可以不写,因为它是默认值。]

The "pull" command thus performs two operations: it fetches changes from a remote branch, then merges them into the current branch.

[以上 “pull”命令执行了两个操作:首先是获取远程分支中的修改,然后是将其与当前分支合并。]

When you are working in a small closely knit group, it is not unusual to interact with the same repository over and over again. By defining remote repository shorthand, you can make it easier:

[当我们工作在一个联系密切的小集体中时,经常会发生针对同一个仓库的交互活动,此时通过 git 我们定义一个远程仓库,会让一切变得更简单:]

$ git remote add bob /home/bob/myrepo

With this, Alice can perform the first operation alone using the "git fetch" command without merging them with her own branch, using:

[通过以上命令的设置,Alice 仅用一个“git fetch”命令就可以实现原来的操作,即不用单独使用合并操作。]

$ git fetch bob

Unlike the longhand form, when Alice fetches from Bob using a remote repository shorthand set up with git remote, what was fetched is stored in a remote tracking branch, in this case bob/master. So after this:

[不象原来的复杂命令,Alice 可以得到 Bob 在远程建立的仓库内容,即 bob/master 分支中的内容]

$ git log -p master..bob/master

shows a list of all the changes that Bob made since he branched from Alice's master branch.

[运行上面的命令,可以看到 Bob 在其分支上做出的所有修改。]

After examining those changes, Alice could merge the changes into her master branch:

[检查了这些修改后, Alice 可以将它们合并入自己的分支,如下:]

$ git merge bob/master

This merge can also be done by pulling from her own remote tracking branch, like this:

[该合并命令还可以象如下操作,抽取获得:]

$ git pull . remotes/bob/master

Note that git pull always merges into the current branch, regardless of what else is given on the command line.

[注意:git pull 命令默认进行合并操作。]

Later, Bob can update his repo with Alice's latest changes using

[然后,bob 也可以通过如下命令使用 Alice 的修改更新自己的 repo 仓库:]

$ git pull

Note that he doesn't need to give the path to Alice's repository; when Bob cloned Alice's repository, git stored the location of her repository in the repository configuration, and that location is used for pulls:

[注意:bob 不需要在命令中给出 Alice 的仓库路径;因为当 Bob 克隆 Alice 的仓库时 git 已经将她的仓库位置存储在仓库的配置文件中,并会用于 pull 命令:]

$ git config --get remote.origin.url
/home/alice/project

(The complete configuration created by git-clone is visible using "git config -l", and the git-config(1) man page explains the meaning of each option.)

[我们可以使用“git config -l”查看 git-clone 时的完整的配置情况,git-config(1) 帮助解释了每个选项的含义。]

Git also keeps a pristine copy of Alice's master branch under the name "origin/master":

[Git 同时保存了 Alice 主分支的一份原始拷贝,存放于“origin/master”目录中。]

$ git branch -r
origin/master

If Bob later decides to work from a different host, he can still perform clones and pulls using the ssh protocol:

[如果 Bob 之后决定通过不同的主机工作,Bob此时依然通过 ssh 协议使用克隆和抽取方法,如下:]

$ git clone alice.org:/home/alice/project myrepo

Alternatively, git has a native protocol, or can use rsync or http; see git-pull(1) for details.

[另外,git 远程工作时有自己特定的协议机制,但也可以使用 rsync 或者 http,详细请查看帮助 git-pull(1)]

Git can also be used in a CVS-like mode, with a central repository that various users push changes to; see git-push(1) and git for CVS users.

[Git 同样可以使用类似 CVS 的模式工作,即维护一个中心仓库,不同用户将修改发送到中心仓库中,请查看帮助 git-push(1) 和 git for CVS users]

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 历史是以一系列内部关联的注释信息组成的。我们已经看到 git log 命令可以列出所有注释内容,请注意每次 git log 时 git 都给出 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 命令来查看提交的详细情况,如下:]

$ 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.

[可见,我们将 1b2e1d63ff 命名为 v2.5。如果你想与其他人分享这个名字,比如说发布版本时,你应该创建一个“tag”对象以标识,详细信息查看 git-tag(1) 。]

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

[定义后,Git中每个和提交有关的命令都能够使用这个新的名字,如下面的例子:]

$ 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(1) instead.

[一定要慎用上面最后一个命令:这个命令不仅会让你丢失当前工作目录中所有修改,还会自动删除未来的修改。如果当前分支是包含那些修改的唯一分支,那么那些修改都将会丢失。]

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

[Git grep 命令可以在项目的任何版本中搜索字符串,比如:]

$ git grep "hello" v2.5

searches for all occurrences of "hello" in v2.5. [上面的命令将在项目的2.5版中搜索所有的 ”hello“ 字符串。]

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

[如果你不写 commit 的名字,git grep 将在它管理的所有当前目录中搜索指定字符串,如下:]

$ git grep "hello"

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

[上述命令又可以看作是一种仅对当前 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 命令接受一组提交的操作,也各有几种实现方式,比如查看日志命令,如下 :]

$ 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-release" and "master" diverged from a common commit some time ago, then

[你同时也可以给出提交的范围,(两个值),第二个未必非得继承自第二个;比如 stable 和 master 两个分支某个时候在同一个提交点分开 maybe 相互独立开来了,那么:]

$ git log stable..experimental

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

[上述命令只会列出 experimental 分支的提交,而不会列出 stable 分支的信息,同样:]

$ git log experimental..stable

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

[上述命令只会列出 stable 分支的提交,而不会列出 experimental 分支信息。]

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.

[但是 git log 命令也有缺陷:它必须以列表形式显示提交信息。当开发的历史记录既有分又有合时,git log 显示的的顺序是比较混乱的。]

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,

[大多数同时多人参与开发的项目(比如 linux kernel 或者 git 自身)合并的频率很高,对此 git 有自己的解决办法,即 gitk ,它使历史记录图形化,比如:]

$ 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 "+".)

[以上命令运行我们浏览最近2周内的对 drivers 文件夹中文件的所有修改提交,注意:我们可以调整 gitk 的字符属性,使用快捷键 ctrl 加 - 和 +。]

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 显示:]

$ git show v2.5:Makefile

Next Steps [未来的使用]

This tutorial should be enough to perform basic distributed revision control for your projects. However, to fully understand the depth and power of git you need to understand two simple ideas on which it is based:

[对于使用 git 的基本功能来说,本入门所述内容已经满足要求。但是如果要深入理解 git 以及体会它的强大,需要明确两点:]

  • The object database is the rather elegant system used to store the history of your project—files, directories, and commits.

  • [对象数据库自身是一个非常优秀的系统,它可以存储项目的历史记录,包括文件、文件夹以及修改。]
  • The index file is a cache of the state of a directory tree, used to create commits, check out working directories, and hold the various trees involved in a merge.

  • [索引文件是文件树状态的缓存,用以创建修改,检出工作文件夹,以及记录合并过程中不同的树结构。]

Part two of this tutorial explains the object database, the index file, and a few other odds and ends that you'll need to make the most of git.

[本入门的第二部分解释了对象数据库、索引文件以及其他特性,这些都是我们在充分利用 git 时需要了解的。]

If you don't want to continue with that right away, a few other digressions that may be interesting at this point are:

[但是,还有部分内容,值得我们关注:]

  • git-format-patch(1)git-am(1): These convert series of git commits into emailed patches, and vice versa, useful for projects such as the linux kernel which rely heavily on emailed patches.

  • [git-format-patch(1) 和 git-am(1):这两个命令将把提交注释转换到 email 补丁,反之亦然,这个功能在 linux kernel 开发中非常有用,因为 email 是主要联系工具。]
  • git-bisect(1): When there is a regression in your project, one way to track down the bug is by searching through the history to find the exact commit that's to blame. Git bisect can help you perform a binary search for that commit. It is smart enough to perform a close-to-optimal search even in the case of complex non-linear history with lots of merged branches.

  • [git-bisect(1):当项目中存在需要回滚操作时,追查 bug 的方法通常是在整个历史记录中精确查询错误的修改。 git bisect 可以帮助我们对修改的二进制搜索,其性能优越,特别是在存有多个合并的非线性仓库中。]
  • Everyday GIT with 20 Commands Or So [git 常用20个命令]

  • git for CVS users. [针对CVS用户的git补充]

Last updated 2008-12-20 06:12:42 UTC
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值