1. 安装Git
安装Git版本控制工具只需在Bash中执行命令:
$ sudo apt-get install git
安装完成后配置用户名和邮箱,在Bash中执行:
$ git config --global user.name "your github name"
$ git config --global user.email "your github email"
如需查看配置,可使用以下命令:
$ git config --list
2. 创建版本库
进入需要创建成Git仓库的目录下,在Bash中执行:
$ git init
该命令会在当前目录下新建一个名为”.git”的文件夹,里面的文件是Git用来管理该版本库的,最好不要随便修改;
版本控制系统只能跟踪文本文件的改动,不能跟踪二进制文件的变化;另外在Windows下不要使用记事本编辑文本文件,因为它保存的UTF-8编码的文件开头会添加0xefbbbf的字符;把需要版本管理的文件放在仓库目录或子目录里,使用以下命令添加和提交文件:
$ git add filename $ git commit -m "the commit description"
3. 管理版本库
首先需要了解工作区/暂存区/主分支/版本库之间的关系;可以把刚才使用”git init”命令所在的文件夹看作工作区,不包括里面的”.git”目录;而”.git”目录可以看作版本库;在版本库里面包含暂存区与主分支master;版本库里面还有一个名为HEAD的指针指向master;使用”git add”命令时,实际上是把修改添加到暂存区;当使用”git commit”后,才把暂存区所有的修改提交到master;
在仓库目录文件夹下,可以使用以下命令查看当前仓库状态:
$ git status
之前的”git add”命令实际上是把文件的修改提交到暂存区;当使用”git commit”之后才正式将文件合并到主分支;
如果想查看一些文件做了哪些改动,可执行:
$ git diff #可加上类似"HEAD -- filename"的参数;
该命令会将工作区的文件与最近一次”add”或”commit”的文件进行比较,输出diff格式;Git跟踪并管理的是修改,不是文件;
如果要查看主分支的提交记录,可执行:
$ git log #可加上"--pretty=oneline"输出单行信息;
该命令会输出主分支的提交日志,其中最前面的一串长度为40的数值是commit id(版本号),是使用SHA1计算得到的;
如果需要回退到上一个版本,可使用以下命令:
$ git reset --hard HEAD^
其中HEAD表示当前版本,HEAD^表示上一个版本,以此类推;或者使用HEAD~5表示往上5个版本;该参数也可以使用版本号代替;
如果回退到之前版本后又想返回新版本,以上命令就必须使用commit id作为参数;如果不记得commit id,可使用使用以下命令:
$ git reflog
Git会记录对主分支的commit/reset/checkout/merge等操作,使用该命令即可查看操作记录;
如果要撤销修改,需要分为三种情况:未提交到暂存区/已提交到暂存区/已提交到本地版本库;
对于第一种情况,需要取消工作区修改,可使用以下命令:
$ git checkout -- filename
该命令会把名为”filename”的文件在工作区的修改全部取消,使该文件回到最近一次commit或add的状态;
对与第二种情况,需要取消暂存区修改,可使用以下命令:
$ git reset HEAD filename
该命令会撤销暂存区的修改,但不影响工作区的修改;此时工作区与HEAD还是存在差异的,若要取消工作区修改,可参考第一种情况;
对于第三中情况,需要对版本进行回退,比如回退到上一个版本:
$ git reset --hard HEAD^
工作区中删除了文件也是属于修改操作,可以使用以下命令删除文件并提交修改:
$ git rm filename #效果与删除文件后执行"git add filename"似乎是一样的
$ git commit -m "remove filename"
删除文件后,如果想要恢复,可使用以下命令:
$ git checkout -- filename
该命令会使文件回到最近一次commit或add的状态,但使用”git rm”后文件就已经处于add状态,所以可能会丢失最近一次提交后修改的内容;
4. 远程仓库
以GitHub为例,首先需要生成密钥文件,在Bash中执行:
$ ssh-keygen -t rsa -C "your github email"
接下来会询问路径和密码,直接回车默认即可;执行成功后会在~/.ssh目录下生成密钥文件;
打开GitHub-Settings-SSH and GPG keys-New SSH key,在Key文本框中填入刚生成的id-rsa.pub文件里的内容,Title任意;
配置完成后需测试,在Bash中执行:
$ ssh git@github.com
如果执行结果中出现”Hello xxxx!”的字样,则说明配置成功,可通过SSH方式访问GitHub仓库;
完成以上操作后,需要在GitHub上创建一个新仓库;登录后点击右上角的加号,选择New repository,在页面中输入仓库名/描述等信息,点击创建;
创建好GitHub上的仓库后,可以进行两种操作,一个是克隆仓库到本地,另一个是把本地的仓库与新仓库关联;
对于第一种操作,一般适用与从零开始开发,可使用以下命令克隆仓库:
$ git clone git@github.com:xxxx/xxxx.github.io.git #参数需要根据实际仓库地址修改,也可以添加文件夹参数
该命令会在当前目录生成名为”xxxx.github.io”的文件夹,里面与GitHub上的内容一致;
该命令地址也可以使用https形式,但https形式每次推送必须输入口令;采用SSH协议速度最快;
文件修改完成后,可以使用:
$ git push origin master #Git中远程库默认名字为origin
对于第二种操作,一般适用与本地已经存在项目文件,可使用以下命令关联远程仓库:
$ git remote add origin git@github.com:xxxx/xxxx.github.io.git
其中origin为远程库的名字,可以使用其它名字;
关联远程库之后就可以将本地库的内容推送到远程库,使用以下命令:
$ git push -u origin master
该命令第一次使用时需要加上”-u”参数,执行后会将master分支的内容推送到远程的master分支,并将两个分支关联起来;以后推送就不用添加”-u”参数了;
另外,第一次使用clone或push命令时,可能会出现SSH警告需要确认服务器的Key的指纹信息来源,输入yes即可;如果需要对照指纹可以访问 GitHub’s SSH key fingerprints
5. 分支管理
Git分支的工作原理,如果只有master分支,则HEAD指向master,master指向提交,每次该分支上提交master就会前进一步;如果创建一个dev分支,则创建一个指针指向master;切换分支,则将HEAD指向dev,之后的每次提交dev前进一步;合并分支,则把master指向dev的提交,如果只有一个子分支,则可以进行快速合并;合并之后,可以将dev分支删除掉;
创建dev分支并切换到该分支,可使用以下命令:
$ git checkout -b dev #创建并切换
该命令相当于以下两条命令:
$ git branch dev #创建
$ bit checkout dev #切换
查看当前分支,可使用以下命令:
$ git branch #输出结果中带*号的为当前分支
合并分支,需要先切换回master分支,可使用以下命令:
$ git checkout master $ git merge dev #合并指定分支到当前分支
合并完成后,可以把dev分支删除,使用以下命令:
$ git branch -d dev #删除分支
当分支的提交出现分叉时,在合并时就可能会产生冲突,比如在master和dev下都各自有新的提交,此时无法进行快速合并;
当出现冲突时,merge命令会提示冲突及冲突文件,也可以使用status命令查看冲突文件,这时候就需要手动修改Git在冲突文件中标记出的不同内容,然后在add/commit;
分支合并完成后可以使用以下命令查看分支合并图:
$ git log --graph --pretty=oneline --abbrev-commit
合并分支时如果使用Fast forward模式,删除分支后会丢失分支信息;如果想保留分支信息可使用以下命令:
$ git merge --no-ff -m "merge with no-ff" dev
该命令会在merge时生成一个新的commit,故需要传入commit描述;
分支管理策略:基本分支包含master和dev,团队每个人有自己的分支;在master分支上发布稳定的新版本,每个人在自己的分支上提交,时不时向dev分支上合并,当dev分支稳定时可合并到master上;
当软件出现Bug时,可以创建一个新的分支来修复,修复完成再删除该分支;此时如果需要保存现在的工作现场,可使用以下命令:
$ git stash
执行后使用status命令查看会提示工作是干净的;查看保存的工作现场可使用以下命令:
$ git stash list
此时可以使用以下其中一个命令恢复工作区:
$ git stash apply #恢复后stash不删除,需使用"git stash drop"命令删除 $ git stash pop #恢复后同时将stash删除
可以多次stash,恢复指定的stash可使用以下命令:
$ git stash apply stash@{0} #参数需根据实际情况修改
软件没添加一个新功能最后新建一个feature分支,然后再开发/合并/删除;如果需要删除一个没有被合并的分支,可使用以下命令:
$ git branch -D <name>
从远程仓库克隆时,Git会自动关联本地与远程的master分支,远程库默认名称为origin;查看远程库可使用以下命令:
$ git remote #添加"-v"参数可以显示详细信息
把master分支上的提交推送到远程库,可使用以下命令:
$ git push origin master
也可以用来推送其它分支;通常需要团队协作的分支需要与远程同步,如master/dev分支;
clone命令默认情况下只克隆远程库的master分支;如需要在dev分支上开发,则克隆后需创建远程的dev到本地,使用以下命令:
$ git checkout -b dev origin/dev
如果远程分支上已有新的提交,并且与本地的修改文件也相同,此时会推送失败,需要先把最新的提交提取到本地,解决冲突后提交/推送;
$ git pull #提取最新提交
使用该命令时,本地的分支必须与远程分支链接,否则操作会失败,以dev分支为例,使用以下命令:
$ git branch --set-upstream dev origin/dev #新版本的Git中参数建议写成"--set-upstream-to"
多人协作工作模式:先尝试push;若推送失败,则使用pull尝试合并;若有冲突,则解决冲突后本地提交;再使用push推送;
6. 标签管理
发布新版本时需要在版本库中打个标签,以方便记忆和查找;标签是跟某个commit绑定在一起的;
如果需要在当前分支的最新提交上打一个新标签,可使用命令:
$ git tag v1.0 #可以在后面添加commit id参数打到指定commit上,如"git tag v1.0 6224937"
如需要查看标签,可以用命令:
$ git tag
如果想查看某个标签详细信息,可使用命令:
$ git show <tagname>
如果要创建一个带有说明的标签,可使用命令:
$ git tag -a v1.0 -m "version 1.0 released" 6224937
该命令里的”-a”指定标签名,”-m”指定说明文字;
还可以使用私钥签名一个标签,命令:
$ git tag -s v2.0 -m "signed version 2.0 released" fec145a
该命令签名使用PGP签名,故需要先安装gpg(GunPG);
如果需要删除某个标签,可使用以下命令:
$ git tag -d v1.0
创建的标签都只存储在本地,不会自动推送到远程库;如果需要推送标签,可使用以下其中一条命令:
$ git push origin <tagname> #推送指定标签 $ git push origin --tags #推送全部未推送的标签
如果需要删除远程的某个标签,需要先将本地的标签删除,再使用push删除远程的标签,命令如下:
$ git tag -d v1.0 $ git push origin :refs/tags/v1.0
7. 使用GitHub及码云
GitHub上参与项目流程:先到官方库项目主页下Fork一个源码仓库到自己的账号下;从自己账号下的仓库克隆到本地,如果直接从官方库克隆将不能提交修改;在本地完成修改后,就可以推送到自己账号下的远程仓库;如果希望官方库可以接受自己的修改,可以在GitHub上发起一个Pull request;
国内也有与GitHub相似的Git托管服务,以码云为例;Gitee与GitHub功能类似,并且提供有限制的免费私有库;在Gitee上创建库/配置SSH/PUSH等操作与GitHub上基本类似;
如果希望同时使用GitHub和Gitee,就必须在本地库上同时关联两个远程库,可使用以下命令:
$ git remote -v #查看远程库详细信息 $ git remote rm origin #删除已有远程库
$ git remote add github git@github.com:xxxx/xxxx.github.io.git #此时GitHub远程库名称为"github"
$ git remote add gitee git@gitee.com:xxxx/xxxx.gitee.git #此时Gitee远程库名称为"gitee"
执行以上命令之后,使用push推送时的远程库名称就不再是origin了,比如:
$ git push github master #推送到GitHub
$ git push gitee master #推送到Gitee
8. Git自定义配置
若想要Git的命令输出显示颜色,可使用以下命令:
$ git config --global color.ui true
如果需要Git忽略工作目录下的某些特殊文件,比如数据库密码配置文件/中间文件等,可在工作目录的根目录下新建”.gitignore”文件,然后将需要忽略的文件名填进去即可;也可以直接使用GitHub提供的配置文件.gitignore;在提交的时候将”.gitignore”也提交到版本库;如果文件忽略成功,则status命令会提示”working directory clean”;
忽略文件的原则:忽略操作系统自动生成的文件;忽略编译生成的中间文件等;忽略带有敏感信息的文件;
如果想添加已经被忽略的文件到暂存区,可使用以下命令:
$ git add -f filename #强制添加文件
同时,如果想查看该文件是由.gitignore文件里的哪个规则忽略的,可以使用命令:
$ git check-ignore -v filename #检查规则
若需要为命令配置别名,可使用以下命令:
$ git config --global alias.st status #将"status"命令别名配置为"st"
该命令中的”–global”表示配置全局有效(当前操作系统用户),如不加该参数,则只在当前库下有效;
另一个例子:
$ 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/config”,里面的配置与执行的config命令一致;当前用户的Git配置文件是用户目录下的”.gitconfig”文件;配置文件中的”[alias]”下对应各命令的别名;
9. Git服务器搭建
首先需要安装Git,Bash下执行:
$ sudo apt-get install git
需要创建一个git用户用于运行git服务,执行:
$ sudo adduser git
收集所有需要登录用户的公钥,导入到/home/git/.git/authorized_keys文件中,一行一个;
选择一个目录作为Git仓库并初始化,如/srv/sample.git,在/srv目录中执行:
$ sudo git init --bare sample.git #服务器上的仓库通常以.git结尾
把该仓库目录的所以者改为git,执行:
$ sudo chown -R git:git sample.git
出于安全考虑,需禁用git用户的Shell登录,编辑/etc/passwd文件:
git:x:1001:1001:,,,:/home/git:/bin/bash #修改为
git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell #git-shell每次一登录就退出
修改完成后,git用户可以使用SSH但无法登录Shell;
完成以上步骤之后,就可以克隆远程仓库了,执行:
$ git clone git@server:/srv/sample.git
至此,服务器已经搭建完成;
若团队较多,收集每个人的公钥就比较困难,此时可以使用Gitosis管理公钥;
Git不支持权限控制,如需要进行权限控制,可以使用gitolite;