Git简介:Git是目前世界上最先进的分布式版本控制系统(没有之一)。
在Linux上安装Git
首先,你可以试着输入git,看看系统有没有安装Git:
$ git
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git
像上面的命令,有很多Linux会友好地告诉你Git没有安装,还会告诉你如何安装Git。
如果你碰巧用Debian或Ubuntu Linux,通过一条sudo apt-get install git就可以直接完成Git的安装,非常简单。
老一点的Debian或Ubuntu Linux,要把命令改为sudo apt-get install git-core,因为以前有个软件也叫GIT(GNU Interactive Tools),结果Git就只能叫git-core了。由于Git名气实在太大,后来就把GNU Interactive Tools改成gnuit,git-core正式改为git。
如果是其他Linux版本,可以直接通过源码安装。先从Git官网下载源码,然后解压,依次输入:./config,make,sudo make install这几个命令安装就好了。
在Windows上安装Git
在Windows上使用Git,可以从Git官网直接下载安装程序(https://git-scm.com/downloads)
安装完成后,在开始菜单里找到“Git”->“Git Bash”,蹦出一个类似命令行窗口的东西,就说明Git安装成功!
安装完成后,还需要最后一步设置,在命令行输入:
$ git config --global user.name "Your Name"
$ git config --global user.email "[email protected]"
因为Git是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和Email地址。你也许会担心,如果有人故意冒充别人怎么办?这个不必担心,首先我们相信大家都是善良无知的群众,其次,真的有冒充的也是有办法可查的。
注意git config命令的--global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。
什么是版本库呢?版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
所以,创建一个版本库非常简单,首先,选择一个合适的地方,创建一个空目录:
$ mkdir learngit
$ cd learngit
$ pwd
/e/gittest/learngit
如果你使用Windows系统,为了避免遇到各种莫名其妙的问题,请确保目录名(包括父目录)不包含中文。
第二步,通过git init命令把这个目录变成Git可以管理的仓库:
$ git init
Initialized empty Git repository in /Users/michael/learngit/.git/
瞬间Git就把仓库建好了,而且告诉你是一个空的仓库(empty Git repository),细心的读者可以发现当前目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。
如果你没有看到.git目录,那是因为这个目录默认是隐藏的,用ls -ah命令就可以看见。
首先这里再明确一下,所有的版本控制系统,其实只能跟踪文本文件的改动,比如TXT文件,网页,所有的程序代码等等,Git也不例外。版本控制系统可以告诉你每次的改动,比如在第5行加了一个单词“Linux”,在第8行删了一个单词“Windows”。而图片、视频这些二进制文件,虽然也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制文件每次改动串起来,也就是只知道图片从100KB改成了120KB,但到底改了啥,版本控制系统不知道,也没法知道。
不幸的是,Microsoft的Word格式是二进制格式,因此,版本控制系统是没法跟踪Word文件的改动的,前面我们举的例子只是为了演示,如果要真正使用版本控制系统,就要以纯文本方式编写文件。
因为文本是有编码的,比如中文有常用的GBK编码,日文有Shift_JIS编码,如果没有历史遗留问题,强烈建议使用标准的UTF-8编码,所有语言使用同一种编码,既没有冲突,又被所有平台所支持。
使用Windows的童鞋要特别注意:
千万不要使用Windows自带的记事本编辑任何文本文件。原因是Microsoft开发记事本的团队使用了一个非常弱智的行为来保存UTF-8编码的文件,他们自作聪明地在每个文件开头添加了0xefbbbf(十六进制)的字符,你会遇到很多不可思议的问题,比如,网页第一行可能会显示一个“?”,明明正确的程序一编译就报语法错误,等等,都是由记事本的弱智行为带来的。建议你下载Notepad++代替记事本,不但功能强大,而且免费!记得把Notepad++的默认编码设置为UTF-8 without BOM即可:
新建文本文件readme.txt,一定要放到learngit目录下(子目录也行),因为这是一个Git仓库,放到其他地方Git再厉害也找不到这个文件。
git add readme.txt
git commit -m "本次提交的说明"
-m后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。
工作区(Working Directory)
就是你在电脑里能看到的目录,比如我的learngit文件夹就是一个工作区
版本库(Repository)
工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
我们把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。
因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。
可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。
常用操作
git add filename 将文件添加到仓库
git commit -m "本次提交的说明" 将文件提交到仓库
git status 命令可以让我们时刻掌握仓库当前的状态
git diff filename 查看该文件具体修改了什么内容
git log 查看从最近到最远的提交日志
git log --pretty=oneline 查看简化的提交日志(commit id版本号和修改内容)
git reset --hard HEAD^ 回退到上一个版本
git reset --hard 版本号(可以简写取前面一段6-8位) 指定回到某个版本
git reflog 用来记录你的每一次命令
cat filename 查看该文件内容
git diff HEAD --filename 查看工作区和版本库里面最新版本的区别
git checkout --filename 把filename文件在工作区的修改全部撤销,这里有两种情况:
一种是filename自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
一种是filename已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit或git add时的状态。
git reset HEAD filename 可以把暂存区的修改撤销掉(unstage),重新放回工作区
git rm filename 删除文件
在连接远程仓库之前,请自行注册GitHub账号。由于你的本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,所以,需要一点设置:
第1步:创建SSH Key。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步。如果没有,打开Shell(Windows下打开Git Bash),创建SSH Key:
$ ssh-keygen -t rsa -C "[email protected]" 引号里为你的github账户邮箱地址
然后一路回车,使用默认值即可
第2步:登陆GitHub,打开“Account settings”,“SSH Keys”页面:
然后,点“Add SSH Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容(最好用notepad打开)
点“Add Key”,就应该看到已经添加的Key
为什么GitHub需要SSH Key呢?因为GitHub需要识别出你推送的提交确实是你推送的,而不是别人冒充的,而Git支持SSH协议,所以,GitHub只要知道了你的公钥,就可以确认只有你自己才能推送。
首先,登陆GitHub,然后,在右上角找到“Create a new repo”按钮,创建一个新的仓库
在Repository name填入learngit,其他保持默认设置,点击“Create repository”按钮,就成功地创建了一个新的Git仓库
git remote add origin [email protected]:yourname/learngit.git
千万注意,把上面的yourname替换成你自己的GitHub账户名
下一步,就可以把本地库的所有内容推送到远程库上
$ git push -u origin master
出现如下信息则说明提交成功
Counting objects: 17, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (13/13), done.
Writing objects: 100% (17/17), 1.90 KiB | 648.00 KiB/s, done.
Total 17 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), done.
To github.com:PeerlessPrince/learnGit.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
遇到错误时常用操作
$ git push -u origin master
Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
提交时遇到此类错误,请检查sshkey是否生成错误或粘贴到github时是否自动添加了空格或回车
git remote -v 查看当前连接的仓库信息
git remote rm origin 删除当前连接的仓库
把本地库的内容推送到远程,用git push命令,实际上是把当前分支master推送到远程。
由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。
推送成功后,可以立刻在GitHub页面中看到远程库的内容已经和本地一模一样:
首先,登陆GitHub,创建一个新的仓库,名字叫gitskills
勾选Initialize this repository with a README,这样GitHub会自动为我们创建一个README.md文件。创建完毕后,可以看到README.md文件
git clone [email protected]:yourname/gitskells.git
创建与合并分支
git branch 查看分支,当前分支前带一个*
git branch 创建分支
git checkout 切换分支
git checkout -b 创建+切换分支
git merge 合并某分支到当前分支(合并前注意切换分支)
git branch -d 删除分支
git branch -D 强行删除分支
解决冲突
冲突一般发生在两个分支同时修改文件时,并在两个分支提交,在合并两个分支时会发生冲突
git log --graph --pretty=oneline --abbrev-commit 查看分支合并情况
当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。
用git log --graph命令可以看到分支合并图
分支管理策略
通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
git merge --no-ff -m "merge with no-ff" dev 合并dev分支,请注意--no-ff参数,表示禁用Fast forward
因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。
在实际开发中,我们应该按照几个基本原则进行分支管理:
首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;
你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。
Bug分支
git stash 把当前工作现场“储藏”起来,等以后恢复现场后继续工作
git stash list 查看暂存的工作现场
git stash apply 恢复工作现场但是恢复后,stash内容并不删除,需要用git stash drop来删除
git stash pop 恢复的同时把stash内容也删了
可以多次stash,恢复的时候,先用git stash list查看,然后恢复指定的stash,用命令git stash apply stash@{0}
git push origin master 推送分支
git pull 抓取分支,从远程抓取分支,使用git pull,如果有冲突,要先处理冲突
git checkout -b branch-name origin/branch-name 在本地创建和远程分支对应的分支,本地和远程分支的名称最好一致
git branch --set-upstream branch-name origin/branch-name 建立本地分支和远程分支的关联,
创建标签
首先切换到需要打标签的分支上
使用命令 git tag 就可以打一个新标签
git tag v1.0
git tag 查看所有标签
git tag tagname commitid 对commitid这次的提交打标签名字为tagname
git show tagname 查看标签信息
git tag -a tagname -m "说明文字" commitid 创建带有说明的标签,用-a指定标签名,-m指定说明文字
git tag -s tagname -m "说明文字" commitid 用私钥签名一个标签
操作标签
git tag -d tagname 删除标签
git push origin tagname 推送某个标签到远程
git push origin --tags 一次性推送全部尚未推送到远程的本地标签
如果标签已经推送到远程,要删除远程标签,先从本地删除
git tag -d tagname
然后,从远程删除
git push origin:refs/tags/tagname
国内的Git托管服务——码云https://gitee.com/
git config --global color.ui true 设置git颜色,会让命令输出看起来更醒目
忽略特殊文件
有些时候,你必须把某些文件放到Git工作目录中,但又不能提交它们,比如保存了数据库密码的配置文件啦,等等,每次git status都会显示Untracked files ...
在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。
GitHub已经为我们准备了各种配置文件,只需要组合一下就可以使用了。所有配置文件可以直接在线浏览:https://github.com/github/gitignore
忽略文件的原则是:
1.忽略操作系统自动生成的文件,比如缩略图等;
2.忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;
3.忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。
git add -f filename 强制添加被忽略的文件到git
git check-ignore -v filename 查看是哪个规则忽略了此文件
配置别名
git config --global alias.st status 使用st代替status
$ git config --global alias.co checkout
$ git config --global alias.ci commit
$ git config --global alias.br branch
--global参数是全局参数,也就是这些命令在这台电脑的所有Git仓库下都有用。
git config --global alias.unstage 'reset HEAD' 命令git reset HEAD file可以把暂存区的修改撤销掉(unstage),重新放回工作区。既然是一个unstage操作,就可以配置一个unstage别名
git config --global alias.last 'log -1' 配置一个git last,让其显示最近一次的提交
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配置文件都放在.git/config文件中,别名就在[alias]后面,要删除别名,直接把对应的行删掉即可
参考:搭建git服务
大部分内容参考自廖学峰老师官网:廖学峰老师官网