-
Notifications
You must be signed in to change notification settings - Fork 0
Tutorial
gittutorial - 一个介绍Git的教程
git *
这个教程解释了怎样将一个新的项目导入到Git,进行更改,和分享更改给其他的开发者。
如果你首先对使用git拉取一个项目感兴趣,例如:体验最新的版本,你可能更加喜欢从The Git User's Manual //TODO 的前两章开始。
首先,注意你可以使用命令获取记录文档,比如:git log --graph,通过一下命令获取命令帮助:
$ man git-log
or:
$ git help log
稍后,你可以使用这个手册阅读你需要的部分;查看git-help // TODO 获取更多信息。
这是一个好主意,向Git介绍你自己,使用你的名称和公开邮箱在做任何操作之前。最简单的操作方式是:
$ git config --global user.name "Your Name Comes Here"
$ git config --global user.email you@yourdomain.example.com
假设你有一个原始的包project.tar.gz用来初始化你的工作。你可以这样将它放在Git版本下。
$ tar xzf project.tar.gz
$ cd project
$ git init
Git将返回
Initialized empty Git repository in .git/
你现在已经初始了工作目录-你可以注意到一个新的目录被创建了,叫做".git"。
下一步,告诉Git在当前目录下建立所有文件的快照(注意"."),使用git add:
$ git add .
这个快照现在存储在一个临时的区域,Git叫它"index"。你可以使用git commit永久存储这个index的内容在仓库中。
$ git commit
这里将提示你填写提交的描述信息。现在你已经在Git上存储了你项目的第一个版本。
更新一些文件,然后将他们更新的内容添加到index:
$ git add file1 file2 file3
你现在已经准备好了要提交的内容。你可以使用git diff命令和--cached选项看见关于要提交的内容
$ git diff -cached
(不使用--cached,git diff 将展示给你已经发生但是还没有加入到index中的变更),你也可以获取当前情况的简单总结使用git status:
$ git status
On branch master
Changes to be committed:
Your branch is up to date with 'origin/master'
(use "git restore --staged <file>..." to unstage)
modified: file1
modified: file2
modified: file3
如果未来你需要任何调整,现在这样做,然后加入任何新的更改到index。最后提交你的改变。
$ git commmit
这将再一次提示你填写信息描述你的改变,然后会对你的项目记录一个新的版本。
或者,替代事先使用git add,你可以使用
$ git commit -a
你可以注意到,任何改变的文件(除了新的文件),被加入到了index,然后提交,都在一步完成。
提交信息的注意点:尽管不是必要的,但使用简短的一行(少于50个字符)总结这次改变作为提交信息的开始是一个好主意,随后是一个空行,然后是详尽的描述。在一次提交信息中,文本会把从开头到第一个空行的内容作为提交标题,并且这个标题从始至终都会被贯彻到Git的使用中。例如,git-format-patch[1] //TODO 将一个提交发送到邮箱,并且使用标题作为主题行,其他的提交内容作为邮箱内容。
许多版本控制系统提供add命令告诉系统开始跟踪一个新文件的变化。Git的add命令做了一些更简单和更有用的事:git add对新文件和有新变化的文件都可以使用,在这两个情况下,Git对这些文件打一个快照然后把内容放到"index"中,为下一次提交做准备。
在任何节点,你都可以查看变化历史,使用
$ git log
如果,你还想在每一步查看完整的区别,使用
$ git log -p
经常查看变化对每一步的把握是有用的
$ git log --stat --summary
一个Git仓库可以包含很多个开发分支。创建一个新的分支叫做"experimental",使用
$ git branch experimental
如果你现在运行
$ git branch
你将会得到一个所有已存在的分支列表
experimental
* master
"experimental"分支是你刚刚创建的,"master"分支是为你自动创建的默认分支。"*"标记你当前所处分支。
$ git switch experimental
切换到"experimental"分支。编辑一个文件,提交改变,然后切回master分支。
(edit file)
$ git commit -a
$ git switch master
现在你做的改变应该已经不可见了,因为改变在exprimental分支上然后你会到了master分支。 你可以在master分支做不同的改变:
(edit file)
$ git commit -a
这时两个分支有了分歧,每个都做了不同的改变。将experimental分支做的改变合并到master
$ git merge experimental
如果改变没有冲突,你的工作已经完成了。如果他们有冲突,在问题文件的左边将会有标记
$ git diff
将会展示出冲突。一旦你编辑了文件解决了冲突
$ git commit -a
将提交合并的结果。最后
gitk
将会展示一个图形界面来表示发生的历史。
这时你可以删除experimental分支,使用
$ git branch -d experimental
这个命令保证在experimental分支上的改变已经在当前分支上。
如果你在crazy-idea分支上开发,然后后悔了,你可以总是使用下面命令删除分支
$ git branch -D crazy-idea
分支是便宜和简单的,因此这是尝试一些东西的好方法。
假设Alice使用Git仓库开始了一个项目在/home/alice/project目录,然后Bob,在相同的机器有一个home目录,想贡献代码。
Bob使用下面命令开始:
bob$ git clone /home/alice/project myrepo
这会创建一个新的myrepo目录包含Alice仓库的克隆。这份克隆与原始项目有同等资格,处理它自己的副本。
Bob做了些更改并且提交:
(edit files)
bob$ git commit -a
(repeat as necessary)
当他准备好了,他告诉Alice在/home/bob/myrepo目录从仓库中拉取改变。
alice$ cd /home/alice/project
alice$ git pull /home/bob/myrepo master
这个命令合并改变从Bob的master分支到Alice的当前分支。如果Alice在机器上做了自己的改变,她可能需要手动修复一些冲突。
"pull"命令因此执行了两个操作:它从远程分支拉取了改变,然后把他们合并到了当前分支。
注意,通常,Alice希望她本地的改变在"pull"之前提交。如果Bob的工作与Alice做的冲突,Alice将使用她的工作树和index解决冲突,并且本地存在的改变将妨碍冲突解决程序(Git将依然执行拉取但拒绝合并--Alice将必须用一些方法除去她本地的改变并且再次拉取)。
Alice可以使用"fetch"命令在合并之前看Bob做了什么;这可以让Alice检查Bob做了什么,用一个特别的标记"FETCH_HEAD",做了决定是否他有一些有价值的拉取,像这样:
alice$ git fetch /home/bob/myrepo master
alice$ git log -p HEAD..FETCH_HEAD
即使Alice没有提交本地的改,这个操作也是安全的变。范围符号"HEAD..FETCH_HEAD"意思是"展示所有可从FETCH_HEAD获得的,并除去一些从HEAD获得的"。Alice已经知道了她用这个命令还没有看见的她当前情况的所有事情(HEAD),并且查看了Bob在他的情况(FETCH_HEAD)的事情。
如果Alice想图形化自从他们的历史被fork之后Bob做的事情,可以使用下面的命令解决:
$ gitk HEAD..FETCH_HEAD
这使用了相同的两个逗号做范围标记,我们之前用git log看见过的。
Alice可能想去浏览自从他们fork了之后他们做了什么。她可以使用三个逗号代替两个逗号:
$ gitk HEAD...FETCH_HEAD
这个意思是"展示任何一个可以获取到的东西,但除了他们两个之中都可以获取到的"。
请注意,这个范围标记可以被用于gitk和"git log"。
检查了Bob做的内容之后,如果没有紧急的东西,Alice可以决定继续工作,在不从Bob那拉取的情况下。如果Bob的历史确实有一些Alice马上需要的,Alice可以选择先贮藏她正在做的工作,做一个"拉取",然后最后应用正在工作的贮藏在历史的头部。
当你正工作在一个小的紧密结合的团队中,在同一个仓库一遍遍的互相影响是正常的。通过定义远程仓库简写,你可以使它更简单。
alice$ git remote add bob /home/bob/myrepo
使用这个命令,Alice可以单独执行"拉取"操作的第一部分,使用git fetch命令,而不合并他们到你自己的分支,使用
alice$ git fetch bob
不像普通写法,当Alice用git remote使用远程仓库简写从Bob拉取时,拉取下来的内容将会被存储在一个远程跟踪分支,在这个例子中是bob/master。因此这之后
alice$ git log -p master..bob/master
展示一个,自从他从Alice的master分支拉了分支之后,Bob做的所有改变的列表。
当检查完这些改变之后,Alice可以将改变合并到他的master分支
alice$ git merge bob/master
这个merge命令也可以通过从她自己的远程跟踪分支拉取来做,像这样
alice$ git pull . remotes/bob/master
注意,"git pull"总是合并到当前分支,不管命令行还提供了其他什么东西。
然后,Bob可以使用Alice最后的改变更新他的仓库
bob$ git pull
注意,他不需要提供Alice仓库的地址。当Bob克隆了Alice的仓库,Git就存储了她的地址在仓库的配置中,并且这个地址在拉取时被使用
bob$ git config --get remote.origin.url
/home/alice/project
(完整的配置是在git clone时创建的,使用git config -l看见,并且git-config[1] //TODO 的帮助页解释了每个选项的意思)
Git也保存了Alice的master分支的原始备份,名字叫"origin/master"。
bob$ git branch -r
origin/master
如果Bob后面决定在另一个不同的主机上工作,他一样可以执行克隆和拉取命令,使用ssh协议
bob$ git clone alice.org:/home/alice/project myrepo
作为一种选择,Git有原生的协议,或者使用http;查看git-pull[1] //TODO 获取详情。
Git也可以被用在CSV之类的模式下,不同的用户向一个中心化的仓库推送改变;查看git-push[1]和gitcvs-migration[7] //TODO
thank you!
git
config
help
bugreport
init
clone
add
status
diff
commit
notes
restore
reset
rm
mv
branch
checkout
switch
merge
mergetool
log
stash
tag
worktree
fetch
pull
push
remote
submodule
show
log
diff
difftool
range-diff
shortlog
describe
apply
cherry-pick
diff
rebase
revert
bisect
blame
grep
gitattributes
Command-line interface conventions
Everyday Git
Frequently Asked Questions (FAQ)
Glossary
Hooks
gitignore
gitmodules
Revisions
Submodules
Tutorial
Workflows
All guides...