一、追踪分支
1.追踪分支
在Git中‘追踪分支’是用于联系本地分支和远程分支的. 如果你在’追踪分支'(Tracking Branches)上执行推送(push)或拉取(pull)时,它会自动推送(push)或拉取(pull)到关联的远程分支上. 如果你经常要从远程仓库里拉取(pull)分支到本地,并且不想很麻烦的使用"git pull "这种格式; 那么就应当使用‘追踪分支'(Tracking Branches). git clone‘命令会自动在本地建立一个'master'分支,它是'origin/master'的‘追踪分支’. 而'origin/master'就是被克隆(clone)仓库的'master'分支. 你可以在使用'git branch'命令时加上'--track'参数, 来手动创建一个'追踪分支'.
$ git branch --track experimental origin/experimental
当你运行下命令时:
$ git pull experimental
它会自动从‘origin'抓取(fetch)内容,再把远程的'origin/experimental'分支合并进(merge)本地的'experimental'分支. 当要把修改推送(push)到origin时, 它会将你本地的'experimental'分支中的修改推送到origin的‘experimental'分支里, 而无需指定它(origin).
三、使用Git Grep进行搜索
1.使用Git Grep进行搜索
用git grep 命令查找Git库里面的某段文字是很方便的. 当然, 你也可以用unix下的'grep'命令进行搜索, 但是'git grep'命令能让你不用签出(checkout)历史文件, 就能查找它们. 例如, 你要看 git.git这个仓库里每个使用'xmmap'函数的地方, 你可以运行下面的命令:
$ git grep xmmap
如果你要显示行号, 你可以添加'-n'选项:
$ git grep -n xmmap
如果我们想只显示文件名, 我们可以使用'--name-onley'选项:
$ git grep --name-only xmmap
我们用'-c'选项可以查看每个文件里有多少行匹配内容(line matches):
$ git grep -c xmmap
现在, 如果我们要查找git仓库里某个特定版本里的内容, 我们可以像下面一样在命令行末尾加上标签名(tag reference):
$ git grep xmmap v1.5.0
我们也可以组合一些搜索条件, 下面的命令就是查找我们在仓库的哪个地方定义了'SORT_DIRENT'.
$ git grep -e '#define' --and -e SORT_DIRENT
我不但可以进行“与"(both)条件搜索操作,也可以进行"或"(either)条件搜索操作.
$ git grep --all-match -e '#define' -e SORT_DIRENT
我们也可以查找出符合一个条件(term)且符合两个条件(terms)之一的文件行.例如我们要找出名字中含有‘PATH'或是'MAX'的常量定义:
$ git grep -e '#define' --and ( -e PATH -e MAX )
四、Git的撤销操作 - 重置, 签出 和 撤销
1.修复未提交文件中的错误(重置)
如果你现在的工作目录(work tree)里搞的一团乱麻, 但是你现在还没有把它们提交; 你可以通过下面的命令, 让工作目录回到上次提交时的状态(last committed state):
$ git reset --hard HEAD
这条命令会把你工作目录中所有未提交的内容清空(当然这不包括未置于版控制下的文件 untracked files). 从另一种角度来说, 这会让"git diff" 和"git diff --cached"命令的显示法都变为空. 如果你只是要恢复一个文件,如"hello.rb", 你就要使用 git checkout
$ git checkout -- hello.rb
这条命令把hello.rb从HEAD中签出并且把它恢复成未修改时的样子.
2.修复已提交文件中的错误
如果你已经做了一个提交(commit),但是你马上后悔了, 这里有两种截然不同的方法去处理这个问题: 创建一个新的提交(commit), 在新的提交里撤消老的提交所作的修改. 这种作法在你已经把代码发布的情况下十分正确. 你也可以去修改你的老提交(old commit). 但是如果你已经把代码发布了,那么千万别这么做; git不会处理项目的历史会改变的情况,如果一个分支的历史被改变了那以后就不能正常的合并. 创建新提交来修复错误 创建一个新的,撤销(revert)了前期修改的提交(commit)是很容易的; 只要把出错的提交(commit)的名字(reference)做为参数传给命令: git revert就可以了; 下面这条命令就演示了如何撤消最近的一个提交:
$ git revert HEAD
这样就创建了一个撤消了上次提交(HEAD)的新提交, 你就有机会来修改新提交(new commit)里的提交注释信息. 你也可撤消更早期的修改, 下面这条命令就是撤销“上上次”(next-to-last)的提交:
$ git revert HEAD^
在这种情况下,git尝试去撤销老的提交,然后留下完整的老提交前的版本. 如果你最近的修改和要撤销的修改有重叠(overlap),那么就会被要求手工解决冲突(conflicts), 就像解决合并(merge)时出现的冲突一样. 译者注: git revert 其实不会直接创建一个提交(commit), 把撤销后的文件内容放到索引(index)里,你需要再执行git commit命令,它们才会成为真正的提交(commit). 修改提交来修复错误 如果你刚刚做了某个提交(commit), 但是你又想马上修改这个提交; git commit 现在支持一个叫--amend的参数,它能让你修改刚才的这个提交(HEAD commit). 这项机制能让你在代码发布前,添加一些新的文件或是修改你的提交注释(commit message). 如果你在老提交(older commit)里发现一个错误, 但是现在还没有发布到代码服务器上. 你可以使用 git rebase命令的交互模式, "git rebase -i"会提示你在编辑中做相关的修改. 这样其实就是让你在rebase的过程来修改提交.
五、维护Git
1.保证良好的性能
在大的仓库中, git靠压缩历史信息来节约磁盘和内存空间. 压缩操作并不是自动进行的, 你需要手动执行 git gc:
$ git gc
压缩操作比较耗时, 你运行git gc命令最好是在你没有其它工作的时候.
2.保持可靠性
git fsck 运行一些仓库的一致性检查, 如果有任何问题就会报告. 这项操作也有点耗时, 通常报的警告就是“悬空对象"(dangling objects).
$ git fsck
“悬空对象"(dangling objects)并不是问题, 最坏的情况只是它们多占了一些磁盘空间. 有时候它们是找回丢失的工作的最后一丝希望.
六、建立一个公共仓库
1.建立一个公共仓库
假设你个人的仓库在目录 ~/proj. 我们先克隆一个新的“裸仓库“,并且创建一个标志文件告诉git-daemon这是个公共仓库.
$ git clone --bare ~/proj proj.git
$ touch proj.git/git-daemon-export-ok
上面的命令创建了一个proj.git目录, 这个目录里有一个“裸git仓库" -- 即只有'.git'目录里的内容,没有任何签出(checked out)的文件. 下一步就是你把这个 proj.git 目录拷到你打算用来托管公共仓库的主机上. 你可以用scp, rsync或其它任何方式.
2.通过git协议导出git仓库
用git协议导出git仓库, 这是推荐的方法. 如果这台服务器上有管理员,TA们要告诉你把仓库放在哪一个目录中, 并且“git:// URL”除仓库目录部分外是什么. 你现在要做的是启动 git daemon; 它会监听在 9418端口. 默认情况下它会允许你访问所有的git目录(看目录中是否有git-daemon-export-ok文件). 如果以某些目录做为 git-daemon 的参数, 那么 git-daemon 会限制用户通过git协议只能访问这些目录. 你可以在inetd service模式下运行 git-daemon; 点击 git daemon 可以查看帮助信息.
3.通过http协议导出git仓库
git协议有不错的性能和可靠性, 但是如果主机上已经配好了一台web服务器,使用http协议(git over http)可能会更容易配置一些. 你需要把新建的"裸仓库"放到Web服务器的可访问目录里, 同时做一些调整,以便让web客户端获得它们所需的额外信息.
$ mv proj.git /home/you/public_html/proj.git
$ cd proj.git
$ git --bare update-server-info
$ chmod a+x hooks/post-update
$ git clone http://yourserver.com/~you/proj.git
$ git clone http://yourserver.com/~you/proj.git
七、建立一个私有仓库
1.通过SSH协议来访问仓库
通常最简单的办法是通ssh协议访问Git(Git Over SSH). 如果你在一台机器上有了一个ssh帐号, 你只要把“git祼仓库"放到任何一个可以通过ssh访问的目录, 然后可以像ssh登录一样简单的使用它. 假设你现在有一个仓库,并且你要把它建成可以在网上可访问的私有仓库. 你可以用下面的命令, 导出一个"祼仓库", 然后用scp命令把它们拷到你的服务器上:
$ git clone --bare /home/user/myrepo/.git /tmp/myrepo.git
$ scp -r /tmp/myrepo.git myserver.com:/opt/git/myrepo.git
如果其它人也在 myserver.com 这台服务器上有ssh帐号,那么TA也可以从这台服务器上克隆(clone)代码:
$ git clone myserver.com:/opt/git/myrepo.git
上面的命令会提示你输入ssh密码或是使用公钥(public key).
八、小结
本节讲了追踪分支,使用Git Grep进行搜索,Git的撤消操作(git reset、git checkout、git revert),维护Git(git gc、git fsck)以及建立公有和私有仓库。
九、练习
请自己建一个公有仓库让小伙伴可以访问。