廖雪峰Git教程3

转自:https://www.liaoxuefeng.com/wiki/896043488029600

【标签管理】

发布一个版本时,咱们一般先在版本库中打一个标签(tag),这样,就惟一肯定了打标签时刻的版本。未来不管何时,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。因此,标签也是版本库的一个快照。python

Git的标签虽然是版本库的快照,但其实它就是指向某个commit的指针(跟分支很像对不对?可是分支能够移动,标签不能移动),因此,建立和删除标签都是瞬间完成的。git

Git有commit,为何还要引入tag?github

“请把上周一的那个版本打包发布,commit号是6a5819e...”sql

“一串乱七八糟的数字很差找!”shell

若是换一个办法:数据库

“请把上周一的那个版本打包发布,版本号是v1.2”bootstrap

“好的,按照tag v1.2查找commit就行!”安全

因此,tag就是一个让人容易记住的有意义的名字,它跟某个commit绑在一块儿。ruby

 

【建立标签】

 

在Git中打标签很是简单,首先,切换到须要打标签的分支上:bash

$ git branch * dev master $ git checkout master Switched to branch 'master' 

而后,敲命令git tag <name>就能够打一个新标签:

$ git tag v1.0 

能够用命令git tag查看全部标签:

$ git tag v1.0 

默认标签是打在最新提交的commit上的。有时候,若是忘了打标签,好比,如今已是周五了,但应该在周一打的标签没有打,怎么办?

方法是找到历史提交的commit id,而后打上就能够了:

$ git log --pretty=oneline --abbrev-commit 12a631b (HEAD -> master, tag: v1.0, origin/master) merged bug fix 101 4c805e2 fix bug 101 e1e9c68 merge with no-ff f52c633 add merge cf810e4 conflict fixed 5dc6824 & simple 14096d0 AND simple b17d20e branch test d46f35e remove test.txt b84166e add test.txt 519219b git tracks changes e43a48b understand how stage works 1094adb append GPL e475afc add distributed eaadf4e wrote a readme file 

比方说要对add merge此次提交打标签,它对应的commit id是f52c633,敲入命令:

$ git tag v0.9 f52c633 

再用命令git tag查看标签:

$ git tag v0.9 v1.0 

注意,标签不是按时间顺序列出,而是按字母排序的。能够用git show <tagname>查看标签信息:

$ git show v0.9 commit f52c63349bc3c1593499807e5c8e972b82c8f286 (tag: v0.9) Author: Michael Liao <askxuefeng@gmail.com> Date: Fri May 18 21:56:54 2018 +0800 add merge diff --git a/readme.txt b/readme.txt ... 

能够看到,v0.9确实打在add merge此次提交上。

还能够建立带有说明的标签,用-a指定标签名,-m指定说明文字:

$ git tag -a v0.1 -m "version 0.1 released" 1094adb 

用命令git show <tagname>能够看到说明文字:

$ git show v0.1
tag v0.1
Tagger: Michael Liao <askxuefeng@gmail.com> Date: Fri May 18 22:48:43 2018 +0800 version 0.1 released commit 1094adb7b9b3807259d8cb349e7df1d4d6477073 (tag: v0.1) Author: Michael Liao <askxuefeng@gmail.com> Date: Fri May 18 21:06:15 2018 +0800 append GPL diff --git a/readme.txt b/readme.txt ... 
 注意:标签老是和某个commit挂钩。若是这个commit既出如今master分支,又出如今dev分支,那么在这两个分支上均可以看到这个标签。

 

小结

  • 命令git tag <tagname>用于新建一个标签,默认为HEAD,也能够指定一个commit id;

  • 命令git tag -a <tagname> -m "blablabla..."能够指定标签信息;

  • 命令git tag能够查看全部标签。

 

【操做标签】

若是标签打错了,也能够删除:

$ git tag -d v0.1 Deleted tag 'v0.1' (was f15b0dd) 

由于建立的标签都只存储在本地,不会自动推送到远程。因此,打错的标签能够在本地安全删除。

若是要推送某个标签到远程,使用命令git push origin <tagname>

$ git push origin v1.0 Total 0 (delta 0), reused 0 (delta 0) To github.com:michaelliao/learngit.git * [new tag] v1.0 -> v1.0 

或者,一次性推送所有还没有推送到远程的本地标签:

$ git push origin --tags Total 0 (delta 0), reused 0 (delta 0) To github.com:michaelliao/learngit.git * [new tag] v0.9 -> v0.9 

若是标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:

$ git tag -d v0.9 Deleted tag 'v0.9' (was f52c633) 

而后,从远程删除。删除命令也是push,可是格式以下:

$ git push origin :refs/tags/v0.9 To github.com:michaelliao/learngit.git - [deleted] v0.9 

要看看是否真的从远程库删除了标签,能够登录GitHub查看。

 

小结

  • 命令git push origin <tagname>能够推送一个本地标签;

  • 命令git push origin --tags能够推送所有未推送过的本地标签;

  • 命令git tag -d <tagname>能够删除一个本地标签;

  • 命令git push origin :refs/tags/<tagname>能够删除一个远程标签。

 

【使用GitHub】

咱们一直用GitHub做为免费的远程仓库,若是是我的的开源项目,放到GitHub上是彻底没有问题的。其实GitHub仍是一个开源协做社区,经过GitHub,既可让别人参与你的开源项目,也能够参与别人的开源项目。

在GitHub出现之前,开源项目开源容易,但让广大人民群众参与进来比较困难,由于要参与,就要提交代码,而给每一个想提交代码的群众都开一个帐号那是不现实的,所以,群众也仅限于报个bug,即便能改掉bug,也只能把diff文件用邮件发过去,很不方便。

可是在GitHub上,利用Git极其强大的克隆和分支功能,广大人民群众真正能够第一次自由参与各类开源项目了。

如何参与一个开源项目呢?好比人气极高的bootstrap项目,这是一个很是强大的CSS框架,你能够访问它的项目主页https://github.com/twbs/bootstrap,点“Fork”就在本身的帐号下克隆了一个bootstrap仓库,而后,从本身的帐号下clone:

git clone git@github.com:michaelliao/bootstrap.git 

必定要从本身的帐号下clone仓库,这样你才能推送修改。若是从bootstrap的做者的仓库地址git@github.com:twbs/bootstrap.git克隆,由于没有权限,你将不能推送修改。

Bootstrap的官方仓库twbs/bootstrap、你在GitHub上克隆的仓库my/bootstrap,以及你本身克隆到本地电脑的仓库,他们的关系就像下图显示的那样:

┌─ GitHub ────────────────────────────────────┐
│                                             │
│ ┌─────────────────┐     ┌─────────────────┐ │
│ │ twbs/bootstrap  │────>│  my/bootstrap   │ │
│ └─────────────────┘     └─────────────────┘ │
│                                  ▲          │
└──────────────────────────────────┼──────────┘
                                   ▼
                          ┌─────────────────┐
                          │ local/bootstrap │
                          └─────────────────┘

若是你想修复bootstrap的一个bug,或者新增一个功能,马上就能够开始干活,干完后,往本身的仓库推送。

若是你但愿bootstrap的官方库能接受你的修改,你就能够在GitHub上发起一个pull request。固然,对方是否接受你的pull request就不必定了。

若是你没能力修改bootstrap,但又想要试一把pull request,那就Fork一下个人仓库:https://github.com/michaelliao/learngit,建立一个your-github-id.txt的文本文件,写点本身学习Git的心得,而后推送一个pull request给我,我会视心情而定是否接受。

小结

  • 在GitHub上,能够任意Fork开源仓库;

  • 本身拥有Fork后的仓库的读写权限;

  • 能够推送pull request给官方仓库来贡献代码。

 

【自定义Git】

安装Git一节中,咱们已经配置了user.nameuser.email,实际上,Git还有不少可配置项。

好比,让Git显示颜色,会让命令输出看起来更醒目:

$ git config --global color.ui true 

这样,Git会适当地显示不一样的颜色,好比git status命令:

git-color

文件名就会标上颜色。

 

【忽略特殊文件】

有些时候,你必须把某些文件放到Git工做目录中,但又不能提交它们,好比保存了数据库密码的配置文件啦,等等,每次git status都会显示Untracked files ...,有强迫症的童鞋内心确定不爽。

好在Git考虑到了你们的感觉,这个问题解决起来也很简单,在Git工做区的根目录下建立一个特殊的.gitignore文件,而后把要忽略的文件名填进去,Git就会自动忽略这些文件。

不须要从头写.gitignore文件,GitHub已经为咱们准备了各类配置文件,只须要组合一下就可使用了。全部配置文件能够直接在线浏览:https://github.com/github/gitignore

忽略文件的原则是:

  1. 忽略操做系统自动生成的文件,好比缩略图等;
  2. 忽略编译生成的中间文件、可执行文件等,也就是若是一个文件是经过另外一个文件自动生成的,那自动生成的文件就不必放进版本库,好比Java编译产生的.class文件;
  3. 忽略你本身的带有敏感信息的配置文件,好比存放口令的配置文件。

举个例子:

假设你在Windows下进行Python开发,Windows会自动在有图片的目录下生成隐藏的缩略图文件,若是有自定义目录,目录下就会有Desktop.ini文件,所以你须要忽略Windows自动生成的垃圾文件:

# Windows: Thumbs.db ehthumbs.db Desktop.ini 

而后,继续忽略Python编译产生的.pyc.pyodist等文件或目录:

# Python: *.py[cod] *.so *.egg *.egg-info dist build 

加上你本身定义的文件,最终获得一个完整的.gitignore文件,内容以下:

# Windows: Thumbs.db ehthumbs.db Desktop.ini # Python: *.py[cod] *.so *.egg *.egg-info dist build # My configurations: db.ini deploy_key_rsa 

最后一步就是把.gitignore也提交到Git,就完成了!固然检验.gitignore的标准是git status命令是否是说working directory clean

使用Windows的童鞋注意了,若是你在资源管理器里新建一个.gitignore文件,它会很是弱智地提示你必须输入文件名,可是在文本编辑器里“保存”或者“另存为”就能够把文件保存为.gitignore了。

有些时候,你想添加一个文件到Git,但发现添加不了,缘由是这个文件被.gitignore忽略了:

$ git add App.class The following paths are ignored by one of your .gitignore files: App.class Use -f if you really want to add them. 

若是你确实想添加该文件,能够用-f强制添加到Git:

$ git add -f App.class 

或者你发现,多是.gitignore写得有问题,须要找出来到底哪一个规则写错了,能够用git check-ignore命令检查:

$ git check-ignore -v App.class .gitignore:3:*.class App.class 

Git会告诉咱们,.gitignore的第3行规则忽略了该文件,因而咱们就能够知道应该修订哪一个规则。

小结

  • 忽略某些文件时,须要编写.gitignore

  • .gitignore文件自己要放到版本库里,而且能够对.gitignore作版本管理!

 

【配置别名】

有没有常常敲错命令?好比git statusstatus这个单词真心很差记。

若是敲git st就表示git status那就简单多了,固然这种偷懒的办法咱们是极力同意的。

咱们只须要敲一行命令,告诉Git,之后st就表示status

$ git config --global alias.st status 

好了,如今敲git st看看效果。

固然还有别的命令能够简写,不少人都用co表示checkoutci表示commitbr表示branch

$ git config --global alias.co checkout $ git config --global alias.ci commit $ git config --global alias.br branch 

之后提交就能够简写成:

$ git ci -m "bala bala bala..." 

--global参数是全局参数,也就是这些命令在这台电脑的全部Git仓库下都有用。

撤销修改一节中,咱们知道,命令git reset HEAD file能够把暂存区的修改撤销掉(unstage),从新放回工做区。既然是一个unstage操做,就能够配置一个unstage别名:

$ git config --global alias.unstage 'reset HEAD' 

当你敲入命令:

$ git unstage test.py 

实际上Git执行的是:

$ git reset HEAD test.py 

配置一个git last,让其显示最后一次提交信息:

$ git config --global alias.last 'log -1' 

这样,用git last就能显示最近一次的提交:

$ git last
commit adca45d317e6d8a4b23f9811c3d7b7f0f180bfe2
Merge: bd6ae48 291bea8
Author: Michael Liao <askxuefeng@gmail.com> Date: Thu Aug 22 22:49:22 2013 +0800 merge & fix hello.py 

甚至还有人丧心病狂地把lg配置成了:

git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit" 

来看看git lg的效果:

git-lg

为何不早点告诉我?别激动,咱不是为了多记几个英文单词嘛!

配置文件

配置Git的时候,加上--global是针对当前用户起做用的,若是不加,那只针对当前的仓库起做用。

配置文件放哪了?每一个仓库的Git配置文件都放在.git/config文件中:

$ cat .git/config [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true ignorecase = true precomposeunicode = true [remote "origin"] url = git@github.com:michaelliao/learngit.git fetch = +refs/heads/*:refs/remotes/origin/* [branch "master"] remote = origin merge = refs/heads/master [alias] last = log -1 

别名就在[alias]后面,要删除别名,直接把对应的行删掉便可。

而当前用户的Git配置文件放在用户主目录下的一个隐藏文件.gitconfig中:

$ cat .gitconfig [alias] co = checkout ci = commit br = branch st = status [user] name = Your Name email = your@email.com 

配置别名也能够直接修改这个文件,若是改错了,能够删掉文件从新经过命令配置。

 

【搭建Git服务器】

远程仓库一节中,咱们讲了远程仓库实际上和本地仓库没啥不一样,纯粹为了7x24小时开机并交换你们的修改。

GitHub就是一个免费托管开源代码的远程仓库。可是对于某些视源代码如生命的商业公司来讲,既不想公开源代码,又舍不得给GitHub交保护费,那就只能本身搭建一台Git服务器做为私有仓库使用。

搭建Git服务器须要准备一台运行Linux的机器,强烈推荐用Ubuntu或Debian,这样,经过几条简单的apt命令就能够完成安装。

假设你已经有sudo权限的用户帐号,下面,正式开始安装。

第一步,安装git

$ sudo apt-get install git 

第二步,建立一个git用户,用来运行git服务:

$ sudo adduser git 

第三步,建立证书登陆:

收集全部须要登陆的用户的公钥,就是他们本身的id_rsa.pub文件,把全部公钥导入到/home/git/.ssh/authorized_keys文件里,一行一个。

第四步,初始化Git仓库:

先选定一个目录做为Git仓库,假定是/srv/sample.git,在/srv目录下输入命令:

$ sudo git init --bare sample.git 

Git就会建立一个裸仓库,裸仓库没有工做区,由于服务器上的Git仓库纯粹是为了共享,因此不让用户直接登陆到服务器上去改工做区,而且服务器上的Git仓库一般都以.git结尾。而后,把owner改成git

$ sudo chown -R git:git sample.git 

第五步,禁用shell登陆:

出于安全考虑,第二步建立的git用户不容许登陆shell,这能够经过编辑/etc/passwd文件完成。找到相似下面的一行:

git:x:1001:1001:,,,:/home/git:/bin/bash 

改成:

git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell 

这样,git用户能够正常经过ssh使用git,但没法登陆shell,由于咱们为git用户指定的git-shell每次一登陆就自动退出。

第六步,克隆远程仓库:

如今,能够经过git clone命令克隆远程仓库了,在各自的电脑上运行:

$ git clone git@server:/srv/sample.git Cloning into 'sample'... warning: You appear to have cloned an empty repository. 

剩下的推送就简单了。

管理公钥

若是团队很小,把每一个人的公钥收集起来放到服务器的/home/git/.ssh/authorized_keys文件里就是可行的。若是团队有几百号人,就无法这么玩了,这时,能够用Gitosis来管理公钥。

这里咱们不介绍怎么玩Gitosis了,几百号人的团队基本都在500强了,相信找个高水平的Linux管理员问题不大。

管理权限

有不少不但视源代码如生命,并且视员工为窃贼的公司,会在版本控制系统里设置一套完善的权限控制,每一个人是否有读写权限会精确到每一个分支甚至每一个目录下。由于Git是为Linux源代码托管而开发的,因此Git也继承了开源社区的精神,不支持权限控制。不过,由于Git支持钩子(hook),因此,能够在服务器端编写一系列脚原本控制提交等操做,达到权限控制的目的。Gitolite就是这个工具。

这里咱们也不介绍Gitolite了,不要把有限的生命浪费到权限斗争中。

相关文章
相关标签/搜索