Day 63 应用工具_Git
Git 的诞生于安装
Git 简介
Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。
Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。
Git 与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持
Git 的诞生
很多人都知道,Linus 在 1991 年创建了开源的 Linux,从此,Linux 系统不断发展,已经成为最大的服务器系统软件了。
Linus 虽然创建了 Linux,但 Linux 的壮大是靠全世界热心的志愿者参与的,这么多人在世界各地为 Linux 编写代码,那 Linux 的代码是如何管理的呢?
事实是,在 2002 年以前,世界各地的志愿者把源代码文件通过 diff 的方式发给 Linus,然后由 Linus 本人通过手工方式合并代码!
你也许会想,为什么 Linus 不把 Linux 代码放到版本控制系统里呢?不是有 CVS、SVN 这些免费的版本控制系统吗?因为 Linus 坚定地反对 CVS 和 SVN,这些集中式的版本控制系统不但速度慢,而且必须联网才能使用。有一些商用的版本控制系统,虽然比 CVS、SVN 好用,但那是付费的,和 Linux 的开源精神不符。
不过,到了 2002 年,Linux 系统已经发展了十年了,代码库之大让 Linus 很难继续通过手工方式管理了,社区的弟兄们也对这种方式表达了强烈不满,于是 Linus 选择了一个商业的版本控制系统 BitKeeper,BitKeeper 的东家 BitMover 公司出于人道主义精神,授权 Linux 社区免费使用这个版本控制系统。
安定团结的大好局面在 2005 年就被打破了,原因是 Linux 社区牛人聚集,不免沾染了一些梁山好汉的江湖习气。开发 Samba 的 Andrew 试图破解 BitKeeper 的协议(这么干的其实也不只他一个),被 BitMover 公司发现了(监控工作做得不错!),于是 BitMover 公司怒了,要收回 Linux 社区的免费使用权。
Linus 可以向 BitMover 公司道个歉,保证以后严格管教弟兄们,嗯,这是不可能的。实际情况是这样的:Linus 花了两周时间自己用 C 写了一个分布式版本控制系统,这就是 Git!一个月之内,
Linux 系统的源码已经由 Git 管理了!牛是怎么定义的呢?大家可以体会一下。
Git 迅速成为最流行的分布式版本控制系统,尤其是 2008 年,GitHub 网站上线了,它为开源项目免费提供 Git 存储,无数开源项目开始迁移至 GitHub,包括 jQuery,PHP,Ruby 等等。
历史就是这么偶然,如果不是当年 BitMover 公司威胁 Linux 社区,可能现在我们就没有免费而超级好用的 Git 了。
Git 与 SVN 的区别
1、GIT 是分布式的,SVN 不是:这是 GIT 和其它非分布式的版本控制系统,例如 SVN,CVS 等,最核心的区别。
2、GIT 把内容按元数据方式存储,而 SVN 是按文件:所有的资源控制系统都是把文件的元信息隐藏在一个类似.svn,.cvs 等的文件夹里。
3、GIT 分支和 SVN 的分支不同:分支在 SVN 中一点不特别,就是版本库中的另外的一个目录。
4、GIT 没有一个全局的版本号,而 SVN 有:目前为止这是跟 SVN 相比 GIT 缺少的最大的一个特征。
5、GIT 的内容完整性要优于 SVN:GIT 的内容存储使用的是 SHA-1 哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。
Git 安装
Centos 下安装 Git,默认在 CentOS 下,我们可以通过 yum 的方式来安装 Git
root@ci‐node1 ~]# yum install git –y root@ci‐node1 ~]# git version git version 1.8.3.1
使用 yum 安装的 Git 的版本是 1.8,版本较低,我们还可以通过源码编译的方式来安装Git 的最新版本。
首先需要安装依赖的库:
root@ci‐node1 ~]# yum install curl‐devel expat‐devel gettext‐devel openssl‐devel zlib‐devel gcc perl‐ExtUtils‐MakeMaker ‐y
下载最新的源码包
root@ci‐node1 src]# cd /usr/local/src/ root@ci‐node1 src]# wget https://www.kernel.org/pub/software/scm/git/git‐2.9.5.tar.gz root@ci‐node1 src]# ll total 5792 ‐rw‐r‐‐r‐‐ 1 root root 5928730 Aug 11 01:57 git‐2.9.5.tar.gz
解压安装:
root@ci‐node1 src]# tar xf git‐2.9.5.tar.gz root@ci‐node1 src]# cd git‐2.9.5 root@ci‐node1 git‐2.9.5]# make prefix=/usr/local/git all root@ci‐node1 git‐2.9.5]# make prefix=/usr/local/git install root@ci‐node1 git‐2.9.5]# rm ‐rf /usr/bin/git root@ci‐node1 git‐2.9.5]# ln ‐s /usr/local/git/bin/git /usr/bin/git root@ci‐node1 git‐2.9.5]# git ‐‐version git version 2.9.5
至此,我们已经完成了 Git 的编译安装,现在 Git 可以安装在 windows、MAC 操作系统上,具体请参考:https://git‐scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5‐%E5%AE%89%E8%A3%85‐Git
Git 的配置
Git 的配置从上到下分三层 system/global/local,使用三个不同参数进行设置,每个层次的配置存储在不同的位置,
1)./etc/gitconfig 文件:包含了适用于系统所有用户和所有库的值。如果你传递参数选项’--system’ 给 git config,它将明确的读和写这个文件。
2).~/.gitconfig 文件 :具体到你的用户。你可以通过传递--global 选项使 Git 读或写这个特定的文件。
3).位于 git 目录的 config 文件 (也就是 .git/config) :无论你当前在用的库是什么,特定指向该单一的库。每个级别重写前一个级别的值。因此,在.git/config 中的值覆盖了在/etc/gitconfig 中的同一个值。
# 设置本仓库的配置信息(用户名) [root@ci‐node1 git_test]# git config ‐‐local user.name wending [root@ci‐node1 git_test]# git config ‐‐local user.email wendong866@163.com # 查看 local 层次的 config 配置信息 [root@ci‐node1 git_test]# git config ‐‐local ‐‐list core.repositoryformatversion=0 core.filemode=true core.bare=false core.logallrefupdates=true user.name=wendong user.email=wendong866@163.com # 通常我们只配置 global 级别。 [root@ci‐node1~]# git config ‐‐global user.name wendong866 [root@ci‐node1 ~]# git config ‐‐global user.email wendong866@163.com [root@ci‐node1 ~]# git config ‐‐list user.name=wendong866 user.email=wendong866@163.com
# 项目配置文件:项目/.git/config git config --local user.name '' git config --local user.email '' # 全局配置文件:~/.gitconfig git config --global user.name '' git config --global user.email '' # 系统配置文件:/etc/.gitconfig,注意:需要有 root 权限 git config --system user.name '' git config --system user.email ''
gitignore忽略文件
有些时候,你必须把某些文件放到Git工作目录中,但又不能提交它们,比如保存了数据库密码的配置文件啦,等等,每次git status
都会显示Untracked files ...
,有强迫症的童鞋心里肯定不爽。
好在Git考虑到了大家的感受,这个问题解决起来也很简单,在Git工作区的根目录下创建一个特殊的.gitignore
文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。不需要从头写.gitignore
文件,GitHub已经为我们准备了各种配置文件,只需要组合一下就可以使用了。所有配置文件可以直接在线浏览:https://github.com/github/gitignore
忽略文件的原则是:
- 忽略操作系统自动生成的文件,比如缩略图等;
- 忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的
.class
文件; - 忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。
使用方法:在当前 git 管理目录下创建:.gitignore 文件。如果让 git 也不管理 .gitignore 在文件中写入即可。
加上你自己定义的文件,最终得到一个完整的.gitignore文件,内容如下:
# Windows: Thumbs.db ehthumbs.db Desktop.ini # Python: *.py[cod] *.so *.egg *.egg-info dist build # My configurations: db.ini deploy_key_rsa
Git 仓库初始化
建仓库
第一步是创建一个空仓库,这是后续操作的前提。
# 使用 bash 命令,切换到用户家目录下: [root@ci-node1 ~]# cd # 在指定目录下创建存放 repo 的文件夹,示例为 git_test [root@ci-node1 ~]# mkdir git_test # 切换到 git_test 目录下 [root@ci-node1 ~]# cd git_test/ [root@ci-node1 git_test]# pwd /root/git_test # 使用 git init 命令创建一个空仓库// 使用 git init 命令创建一个空仓库 [root@ci-node1 git_test]# git init Initialized empty Git repository in /root/git_test/.git/ # 空仓库创建完成后 gittest 文件夹下会生成一个.git 隐藏文件夹。仓库默认包含一个主 支,即 master,默认操作都是在主分支 master 上进行的。 [root@ci-node1 git_test]# ll -a total 0 drwxr-xr-x. 3 root root 18 Jul 20 08:47 . dr-xr-x---. 4 root root 197 Jul 20 08:46 .. drwxr-xr-x. 7 root root 119 Jul 20 08:47 .git
设置过滤文件
有了仓库,我们便可以在 git_test 文件夹下的工作区做文件增删修改工作了,但很多时候,我们只在意开发过程中的源文件,并不需要管理自动产生的其他临时文件。这时候我们便需要一个过滤文件,在这个文件中设置过滤规则,让 Git 能够自动过滤掉那些临时文件,这个文件便是.gitignore 文件。
# 在仓库目录下创建.gitignore 文件 [root@ci-node1 git_test]# touch .gitignore [root@ci-node1 git_test]# vim .gitignore [root@ci-node1 git_test]# cat .gitignore test.txt # 过滤 test.txt 文件 /test/ # 过滤 test 目录 *.txt # 过滤所有以.txt 结尾的文件
常用的通配规则:
以斜杠“/”开头表示目录
以星号“*”通配多个字符
以问号“?”通配单个字符
以方括号“[]”包含单个字符的匹配列表
以叹号“!”表示不忽略(跟踪)匹配到的文件或目录
Git 的区域与状态
Git 的四个区域
Workspace:工作区(他持有实际文件)
Index / Stage / Cached:暂存区(它像一个结存区域,临时保存你的改动)一般存放在 ".git 目录下" 下的 index 文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)
Repository:本地仓库工作区有一个隐藏目录.git,这个不算工作区,而是 Git 的版本库。
Remote:远程仓库
Git 的四种状态
前面讲了 Git 有四个区域,而单就文件改动状态层面而言,Git 区域内的文件也有 4 种状态(需要注意的是文件状态并不是与 Git 区域一一对应的),这是 Git 第二个重要概念。
Untracked:新增的文件的状态,未受 Git 管理,记录在工作区
Modified:受 Git 管理过的文件的改动状态(包括改动内容、删除文件),记录在工作区
Staged:将记录在工作区的文件变动状态通知了 Git,记录在暂存区
Unmodified:受 Git 管理中的文件状态(没有变动),记录在本地仓库/远程仓库
Git 基础命令
git init # 初始化仓库 git remote add item http... # 添加远程仓库地址 git status # 查看文件在工作环境的中的状态 git add file # 添加文件到缓存区,添加多个,文件名称用空格隔开 git add * # 添加所有文件到缓存区 git rm --cached b # 将 b 文件从缓存区移除 gir rm - f c # 将 c 文件同时在缓存区和工作环境中删除 git commit # 将缓存区中的文件提交到本地仓库 git mv old new # 改名,同时把工作区域和本地仓库的文件进行改名 git diff file # 比较工作区域缓存区的文件 git diff --cached file # 比较缓存区域本地仓库的文件 git log # 显示历史提交记录 git log --graph # 以流线图的方式显示提交记录 git log --oneline # 精简信息,在一行中显示 git log --oneline --decorate # 简写信息,并显示所在分支 git log -p # 显示提交的完整信息,包含做了哪些改动 git reflog # 显示所有提交的记录,包含回退后记录 git checkout -- file # 缓存区文件覆盖工作区文件 git reset HEAD file # 本地仓库覆盖缓存区文件 git reset --hard id # 回退到某次 commit git rebase -i HEAD~3 # 表示合并前三次的提交记录,注意不要合并已经提交到远程仓库的记录
Git 快速解决冲突
冲突的原因与避免
原因:
1 多人在同一分支开发
2 分之合并出现冲突
避免:
如果你想少出现冲突,勤拉取代码
使用 Beyond Compare
1、下载 Beyond Compare
2、在 git 中配置
git config --local merge.tool bc4 # 起一个名字,--local 表示只在当前项目有效 git config --local mergetool.path '' # 配置 bc4 的启动路径 git config --local mergetool.keepBackup false # 关闭保留源文件
3、应用 Beyond Compare 解决冲突
git mergetool
使用本地 git 或云上处理
选择合并或选择其一保留,其它的删掉即可
<<<<<<< HEAD 我的代码 print('刘亦菲') ======= 它的代码 print('彭于晏') >>>>>>> 6f720edbd84c8744b1c7c10767fb89a5d0fa98f5
# 我[仓库管理员]创建了仓库,我对仓库有各种权限 # 我们要多人开发(张三,李四),张三李四在自己的仓库中,能看到我的项目吗?看不到 # 我[仓库管理员],把张三李四设置为该仓库的开发者,设置完成后,在张三李四的仓库中就能看到这个项目了 # 仓库管理员,邀请开发者进入 -邀请的开发者,对这个仓库就有读写权限,他们就可以开发代码,提交 # 我作为开发者,本地没有代码 1 把代码从远程仓库 clone 下来 git clone git@gitee.com:liuqingzheng/luffy_api.git 2 使用pycharm打开,配置好解释器,安装依赖 3 开发代码,开发完 git add # 设置用户名和邮箱 git config user.name lqz git config user.email 3@qq.com git commit git push origin master # 你刚去公司,你的步骤 1 自己注册,hr给你 gitlab 账号和密码 -自己去你的账号里,配置ssh 2 老大会把一个仓库地址给你 【它已经把你加成开发者了】 https ssh 3 clone下来代码 4 使用pycharnm打开,配置环境===》代码运行起来 5 开发代码,本地提交---》push到远端 add commit push
# github,gitee 看到好的开源项目, 发现有bug,为他增加新功能---》你加入了代码---》想合并进开源项目,如何做 # 步骤: 1 先fork开源项目--》复制这个项目到我的仓库中 2 clone下来,改代码,一路提交到远端(我的) 3 提交pr,等作者同意
# 你不要用 # 想远程的代码,是最初的状态 # 步骤: 1 本地版本回退 git reset --hard 版本号 2 强行推到远端 git push origin master -f
Git 分支及命令
Git 中的分支,其实本质上仅仅是个指向 commit 对象的可变指针。Git 会使用 master作为分支的默认名字。在若干次提交后,你其实已经有了一个指向最后一次提交对象的master 分支,它在每次提交的时候都会自动向前移动。
git branch name # 创建分支 git branch # 查看分支 git checkout name # 切换分支 git checkout -b name # 创建并切换分支 git merge branch_name # 合并分支 git branch -d name # 删除分支
Git 标签及命令
标签也是版本库的一个快照。Git 的标签虽然是版本库的快照,但其实它就是指向某个commit 的指针
如果你达到一个重要的阶段,并希望永远记住那个特别的提交快照,你可以使用 gittag 给它打上标签。
比如说,我们想为我们的 项目发布一个"1.0"版本。 我们可以用 git tag -a v1.0 命令给最新一次提交打上(HEAD)"v1.0"的标签。-a 选项意为"创建一个带注解的标签"。 不用 -a 选项也可以执行的,但它不会记录这标签是啥时候打的,谁打的,也不会让你添加个标签的注解。 我推荐一直创建带注解的标签。
git tag -a tag_name # 给当前 commit 添加标签 git tag -a tag_name id # 给特定 commit 添加标签 git tag # 查看有哪些标签 git show tag_name # 展示标签内的详细信息 git tag -d tag_name # 删除标签
Github 公有仓库使用
github 是一个基于 git 的代码托管平台,付费用户可以建私人仓库,我们一般的免费用户只能使用公共仓库,也就是代码要公开。
配置ssh-key
在完成Github中创建库后,我们配置对 Github 进行配置,实现我们的本地客户端和Github 无密码登录,我们需要配置 Github 的 SSH KEY。
首先我们在客户端生成 key,在 linux 和 windows 均可使用 ssh-keygen 命令生成,需要注意的是在 windows 下只能生成 rsa 加密方式的 key。
[root@ci-node1 git_test]# ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Created directory '/root/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: SHA256:xC3xX4oQfPDlziNkh1+alXccJYggt/5QcOd9kaoJkaY root@ci-node1 The key's randomart image is: +---[RSA 2048]----+ | ..Boo.o..o+| | +.&o*.. =o| | O.X + B =| | E B B O o.| | S + % | | o + . | | . | | | | | +----[SHA256]-----+ [root@ci-node1 git_test]# ll /root/.ssh/ total 8 -rw------- 1 root root 1675 Aug 1 23:10 id_rsa -rw-r--r-- 1 root root 395 Aug 1 23:10 id_rsa.pub
Github 远程仓库操作
# 添加远程连接 git remote add GitTesg git@github.com:ysging/GitTesg.git # 查看已有的远程连接 git remote # 推送 git push -u GitTesg master # 克隆 git clone git@github.com:ysging/GitTesg.git # 拉取: git fetch + 合并 = git pull git fetch # 查看远程分支 git branch -r # 查看远程分支 git branch -a # 查看所有分支
注意:
如果提交了,再写忽略文件的步骤
luffy.log--->暂存区---》版本库
.gitignore---》写上忽略,但是不好被忽略,只要luffy.log有变化还是会被监控到
删除luffy.log---》会被监控到---》add,commit---》版本库中已经没有luffy.log
再出的luffy.log,就不会被管理了
# 要使用 ssh 方案:需要公钥和私钥 ---》公司里这种方式多 -私钥在本地保存 -公钥配置到 gitee 上 -以后再提交代码,不需要其他任何认证了,一路绿灯 # 使用步骤: -生成公钥私钥:https://gitee.com/help/articles/4181 -在命令窗口中执行,一路回车 ssh-keygen -t ed25519 -C "306334678@qq.com" -生成在:C:\Users\Administrator\.ssh 两个文件,一个公钥,一个私钥 -把公钥,配置在 gitee 上 -之前 origin 对应的地址是 https 的,现在要使用 ssh 提交代码,需要把它删除,再增加成 ssh 的协议 git remote remove origin git remote add origin git@gitee.com:liuqingzheng/luffy_api.git
案例:
1、如何删除Git上的远程文件夹
git rm -r --cached test //--cached不会把本地的test删除 git commit -m 'delete test dir' git push -u origin master
2、删除commit(暂存区)中的文件(git)
解决的问题是:向暂存区提交了多余的文件。 解决方法: git ls-files # 查看暂存区文件 git rm --cache 文件名 # 记住要删除的文件名,从暂存区删除该文件 # 删除后可以再次查看暂存区的文件是否已经删除了,使用命令后都会正常删除 git reset HEAD 文件名 # 让本地与为提交的状态与远程仓库一致
3、创建远程分支
git branch -a # 查看所有分支 git checkout -b test01 # 创建本地test01分支 git push --set-upstream origin test01 # 把本地test01分支推送到远程 git branch -r # 查看远程分支
4、pull 拉取远程指定分支以及 push 推送到远程指定分支
git pull origin <远程分支名>:<本地分支名> # 将远程指定分支 拉取到 本地指定分支上 git pull origin <远程分支名> # 将远程指定分支 拉取到 本地当前分支上 git push origin <本地分支名>:<远程分支名> # 将本地当前分支 推送到 远程指定分支上(注意:pull是远程在前本地在后,push相反) git push origin <本地分支名> # 将本地当前分支 推送到 与本地当前分支同名的远程分支上(注意:pull是远程在前本地在后,push相反)
5、删除分支
git branch -d 分支名称 # 删除本地分支: git branch -D 分支名称 # 强制删除本地分支: git push origin --delete 分支名称 # 删除远程分支:
6、修改分支地址
# 修改命令 git remote set-url origin url # 先删后加 git remote rm origin git remote add origin url