【git企业级代码管理工具使用汇总】
文末添加我的微信公众号,免费帮你答疑~
文章目录
- 一、git基本操作
-
- 认识工作区,暂存区,版本库
-
- 添加文件(场景1)
- 添加文件 (场景2)
- 版本回退
- 撤销修改
- 删除文件
- 二、git分支管理
-
- 创建分支
- 切换分支
- 合并分支
- 删除分支
- 合并冲突
- 三、远程管理
-
- 理解分布式版本控制系统
- 远程仓库
-
- 向远程仓库推送
- 拉取远程仓库到本地
- 配置git文件
- 标签管理
- 总结
ubuntu下安装git的指令:
apt-get install -y git
一、git基本操作
要知道:仓库是进⾏版本控制的⼀个⽂件⽬录。
要对文件进行版本控制,就需要创建一个仓库。
第一步:初始化git仓库。
在文件目录下输入:git init指令。
ll查看隐藏目录可以看到,.git,就成功了。
第二步:配置本地仓库,要把代码上传到远程仓库,就得让本地仓库认识远程仓库。
git config user.name “真实的git仓库的用户名字”
git config user.email “真实邮箱地址”
git config -l 即可查看配置项信息。
如果想重置配置项,
git config --unset user.name
git config --unset user.email
即可。
一个重要的选项命令:–global
git config --global user.name “XXX”
git config user.name “XXX”
两者的区别在于,加了–global选项后,配置的信息是全局的。
因为在本地可以创建多个git仓库的,如果加了–global,这样所有仓库的配置信息都是上面的user.name 和email了。
取消全局的配置:
git config --global --unset user.name
git config --global --unset user.email
即可。
认识工作区,暂存区,版本库
•⼯作区:是在电脑上你要写代码或⽂件的⽬录。
• 暂存区:英⽂叫 stage 或 index。⼀般存放在 .git ⽬录下的 index ⽂件(.git/index)中,我们
把暂存区有时也叫作索引(index)。
• 版本库:⼜名仓库,英⽂名 repository 。⼯作区有⼀个隐藏⽬录 .git ,它不算⼯作区,⽽
是 Git 的版本库。这个版本库⾥⾯的所有⽂件都可以被 Git 管理起来,每个⽂件的修改、删除,Git
都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
所以,.git/ 目录,就是一个版本库,但是,不是把外面的文件放入到.git/目录下,这个文件/文件夹就能被.git仓库追踪!!
并且,是不允许手动修改/新增.git/目录下的任何内容的!否则后续操作会受到很大影响。
图中左侧为⼯作区,右侧为版本库。Git 的版本库⾥存了很多东西,其中最重要的就是暂存区。
• 在创建 Git 版本库时,Git 会为我们⾃动创建⼀个唯⼀的 master 分⽀,以及指向 master 的⼀个指
针叫 HEAD。(分⽀和HEAD的概念后⾯再说)
• 当对⼯作区修改(或新增)的⽂件执⾏ git add 命令时,暂存区⽬录树的⽂件索引会被更新。
• 当执⾏提交操作 git commit 时,master 分⽀会做相应的更新,可以简单理解为暂存区的⽬录
树才会被真正写到版本库中。
由上述描述我们便能得知:通过新建或粘贴进⽬录的⽂件,并不能称之为向仓库中新增⽂件,⽽只是
在⼯作区新增了⽂件。必须要通过使⽤ git add 和 git commit 命令才能将⽂件添加到仓库中
进⾏管理!!!
添加文件(场景1)
在包含 .git 的⽬录下新建⼀个 ReadMe ⽂件,我们可以使⽤ git add 命令可以将⽂件添加到暂存
区:
• 添加⼀个或多个⽂件到暂存区: git add [file1] [file2] …
• 添加指定⽬录到暂存区,包括⼦⽬录: git add [dir]
• 添加当前⽬录下的所有⽂件改动到暂存区: git add .
再使⽤ git commit 命令将暂存区内容添加到本地仓库中:
• 提交暂存区全部内容到本地仓库中: git commit -m “message”
• 提交暂存区的指定⽂件到仓库区: git commit [file1] [file2] … -m “message”
注意 git commit 后⾯的 -m 选项,要跟上描述本次提交的 message,由⽤⼾⾃⼰完成,这部分内
容绝对不能省略,并要好好描述,是⽤来记录你的提交细节,是给我们⼈看的。
加入我要讲README文件,文件内容:hello world,从工作区添加进暂存区
git add README
git commit -m “(这里是对添加的文件的注释,是必须要写的)”
git commit 命令执⾏成功后会告诉我们,1个⽂件被改动(就是我们新添加的ReadMe⽂件),插
⼊了两⾏内容(ReadMe有两⾏内容)。
我们还可以多次 add 不同的⽂件,⽽只 commit ⼀次便可以提交所有⽂件,是因为需要提交的⽂件是
通通被 add 到暂存区中,然后⼀次性 commit 暂存区的所有修改。
还可以通过git log命令,查看历史的提交到暂存区的修改。
接下来查看.git文件
tree .git/
dzt@DESKTOP-JDUA0JN:~/gitcode$ cat .git/HEAD
ref: refs/heads/master
可以看到,HEAD指针指向./git/refs/heads/master
通过查看master,
dzt@DESKTOP-JDUA0JN:~/gitcode$ cat .git/refs/heads/master
e944af3af300a929647ec6fe2efea30b6074bf08
即可看到,最近一次commit时,创建的object对象的ID。
分成两部分,e9是objects目录下的某个object对象的编号,剩下的就是该对象的ID了。
通过
git cat-file -p 最近一次commit时,创建的object对象的ID
如:
即可看到该对象的信息。
添加文件 (场景2)
Git ⽐其他版本控制系统设计得优秀,因为 Git 跟踪并管理的是修改,⽽⾮⽂件。
什么是修改?⽐如你新增了⼀⾏,这就是⼀个修改,删除了⼀⾏,也是⼀个修改,更改了某些字符,
也是⼀个修改,删了⼀些⼜加了⼀些,也是⼀个修改,甚⾄创建⼀个新⽂件,也算⼀个修改。
让我们将 ReadMe ⽂件进⾏⼀次修改:
本来README文件的内容只有第一行,现在新增了两行,导致工作区的README和暂存区的README不一样了。
通过git status命令查看在你上次提交之后是否有对⽂件进⾏再次修改。
上图可以看到,提交的文件中,README已经被修改了,但是修改的部分没有添加到暂存区。
⽬前,我们只知道⽂件被修改了,如果能知道具体哪些地⽅被修改了,就更好了。有人会说,我刚
改的我知道呀!可是,你还记得你三天前写了什么代码吗?或者没写?
所以,使用一个命令即可解决:
git diff filename,就能显示出工作区和暂存区的同一个文件的差异。
可以看到,工作区新增了两行内容。
然后通过git add README命令,把工作区的README文件提交到git仓库的暂存区,就看不到差异了
此时,只需要继续git commit -m “(这里写注释)”
就能将暂存区的内容放入git仓库中了(过程上面讲过,创建了一个object对象)
版本回退
之前我们也提到过,Git 能够管理⽂件的历史版本,这也是版本控制器重要的能⼒。如果有⼀天你发现之前前的⼯作做的出现了很⼤的问题,需要在某个特定的历史版本重新开始,这个时候,就需要版本回退的功能了。
执⾏ git reset 命令⽤于回退版本,可以指定退回某⼀次提交的版本。要解释⼀下“回退”本质是
要将版本库中的内容进⾏回退,⼯作区或暂存区是否回退由命令参数决定:
git reset 命令语法格式为: git reset [–soft | --mixed | --hard] [HEAD]
• --mixed 为默认选项,使⽤时可以不⽤带该参数。该参数将暂存区的内容退回为指定提交版本内
容,⼯作区⽂件保持不变。
• --soft 参数对于⼯作区和暂存区的内容都不变,只是将版本库回退到某个指定版本。
• --hard 参数将暂存区与⼯作区都退回到指定版本。切记⼯作区有未提交的代码时不要⽤这个命
令,因为⼯作区会回滚,你没有提交的代码就再也找不回了,所以使⽤该参数前⼀定要慎重。
HEAD 说明:
◦ 可直接写成 commit id,表⽰指定退回的版本
◦ HEAD 表⽰当前版本
◦ HEAD^ 上⼀个版本
◦ HEAD^^ 上上⼀个版本
◦ 以此类推…
• 可以使⽤ 〜数字表⽰:
◦ HEAD~0 表⽰当前版本
◦ HEAD~1 上⼀个版本
◦ HEAD^2 上上⼀个版本
◦ 以此类推…
举例:接下来分别对README文件进行三次修改并提交到暂存区,然后从暂存区提交到版本库。
查看历史提交记录:
(小tips:git log 和git log --pretty=oneline的区别在于,后者是让显示的内容更好看,以一行显示出来。)
现在,如果我们在提交完 version3 后, 发现 version 3 编写错误,想回退到 version2,重新基于
version 2 开始编写。由于我们在这⾥希望的是将⼯作区的内容也回退到 version 2 版本,所以需
要⽤到 --hard 参数,⽰例如下:
git reset --hard + 要回退到的object版本的的ID号
我们惊奇的发现,此时 ReadMe ⽂件的内容,已经回退到 version2 了!,当前,我们再次⽤ git
log 查看⼀下提交⽇志,发现 HEAD也指向了version2了。
到这⾥⼀般回退功能就演⽰完了,但现在如果我后悔了,想再回到 version 3 怎么办?我们可以继续使⽤ git reset 命令,回退到 version 3 版本,但我们必须要拿到 version 3 的 commit id 去指定回退的版本。但我们看到了 git log 并不能打印出 version 3 的 commit id ,运⽓好的话我们可以从终端
上去找找之前的记录,运⽓不好的话 commit id 已经被我们搞丢了。。。
Git 还提供了⼀个 git reflog 命令能补救⼀下,该命令⽤来记录本地的每⼀次命令。
git reflog
这个3b0059d,其实是–versions 3的commit id的一部分,Git 版本回退的时候,也可以使⽤部分 commit id 来代表⽬标版本。
此时可以看到版本恢复了。
可往往是理想很丰满,现实很⻣感。在实际开发中,由于⻓时间的开发了,导致 commit id 早就找
不到了,可突然某⼀天,我⼜想回退到 version3,那该如何操作呢?貌似现在不可能了。。。
值得说的是,Git 的版本回退速度⾮常快,因为 Git 在内部有个指向当前分⽀(此处是master)的
HEAD 指针, refs/heads/master ⽂件⾥保存当前 master 分⽀的最新 commit id 。当我们
在回退版本的时候,Git 仅仅是给 refs/heads/master 中存储⼀个特定的version,可以简单理解
成如下⽰意图:
撤销修改
如果我们在我们的⼯作区写了很⻓时间代码,越写越写不下去,觉得⾃⼰写的实在是垃圾,想恢复到
上⼀个版本。
情况1:对于工作区的代码,没有add。
做法:1.如果写的代码不多,当然可以直接删掉,但是实际开发中,怎么可能不写得多呢哈哈。。
当然,可以git diff filename,看看工作区和暂存区的代码差别,再删,但是如果代码很多,容易删出问题,删出新的bug。。。
所以,git提供了更好的方式。
做法2:
git checkout – [file]命令让⼯作区的某个⽂件回到最近⼀次 add 或 commit 时的状态。 要注意 git checkout – [file] 命令中的-- 很重要,切记不要省略,⼀旦省略,该命令就变为其他意思了。
情况2:已经add了,但没有commit
add 后还是保存到了暂存区呢?怎么撤销呢?
让我们来回忆⼀下学过的 git reset 回退命令,该命令如果使⽤ --mixed 参数,可以将暂存区
的内容退回为指定的版本内容,但⼯作区⽂件保持不变。那我们就可以回退下暂存区的内容了!!!
那么,如何丢弃工作区的修改呢?
git checkout – README
注意一定要加 – 两个横杠,否则命令的意思就变了!!
情况3:已经add,并且已经commit了
git reset --hard HEAD^ 命令即可。带个尖括号^表示退到上一个版本,后面要加什么,前面讲过了哦。
删除文件
在 Git 中,删除也是⼀个修改操作,我们实战⼀下, 如果要删除 file5 ⽂件,怎么搞呢?如果你这样
做了:
rm -f file5
这样做只是删除了工作区的file5文件,但是,版本库的file5还在。
git status命令会立刻告诉你,哪些文件被删除了。
此时,⼯作区和版本库就不⼀致了,要删⽂件,⽬前除了要删⼯作区的⽂件,还要清除版本库的⽂
件。
⼀般⾛到这⾥,有两种可能:
• 确实要从版本库中删除该⽂件
• 不⼩⼼删错了
对第⼆种情况,很明显误删,需要使⽤ git 来进⾏恢复,很简单,我们刚学过(删除也是修改):
git checkout – file5,让工作区的file5文件回到上一次add/commit时的状态
对于第⼀种情况,很明显是没有删完,我们只删除了⼯作区的⽂件。这时就需要使⽤ git rm 将⽂
件从暂存区和⼯作区中删除,并且 commit :
git rm file5 #从工作区和暂存区删掉file5
git commit -m “delete file5” #更新这个删除到版本库,才算真的删掉,否则版本库还有file5
此时才算彻底删掉file5。
二、git分支管理
创建分支
git branch :查看当前本地现有分支
git branch dev:新建分支dev
当我们创建新的分⽀后,Git 新建了⼀个指针叫 dev, * 表⽰当前 HEAD 指向的分⽀是 master 分
⽀。另外,可以通过⽬录结构发现,新的 dev 分⽀:
ls .git/refs/heads/
还可以发现,dev和master分支指向的是同一个修改,并且,HEAD是指向master分支的。
切换分支
git checkout +分支名
然后在dev分支下,对README文件新增任意一行代码。
然后git add, git commit 提交到暂存区,版本库
然后git checkout master切换会master分支
cat README,发现新增的代码不见了!
原因如下:
当git commit 提交后,dev分支指向了新的提交点,所以与master不一致了。
合并分支
为了能在master分支上看到dev分支的更新,需要将dev分支合并到master分支上。
git checkout master # 切换到master分支上
git merge dev #将dev分支合并到master分支上
删除分支
合并完成后, dev 分⽀对于我们来说就没⽤了, 那么dev分⽀就可以被删除掉,注意如果当前正处于某
分⽀下,就不能删除当前分⽀,如:
git checkout dev
git branch -d dev
此时删除dev分支就会报错,需要切换到其他分支再删。
因为创建、合并和删除分⽀⾮常快,所以Git⿎励你使⽤分⽀完成某个任务,合并后再删掉分⽀,这和
直接在master分⽀上⼯作效果是⼀样的,但过程更安全。
合并冲突
可是,在实际分⽀合并的时候,并不是想合并就能合并成功的,有时候可能会遇到代码冲突的问题。
为了演⽰这问题,创建⼀个新的分⽀ dev1 ,并切换⾄⽬标分⽀,我们可以使⽤ git checkout -b dev1 ⼀步完成创建并切换的动作。
案例如下:
git checkout -b dev1
然后修改README文件(新增一行代码)
git add,commit 后,切换到master分支
再次对README文件修改(新增一行代码)
然后git add,commit后,master分支和dev1分支下的README文件就不一样了。
这种情况下,Git 只能试图把各⾃的修改合并起来,但这种合并就可能会有冲突:如下
此时直接cat README:
Git 会⽤ <<<<<<>>>>>> 来标记出不同分⽀的冲突内容。
此时我们必须要⼿动调整冲突代码,并需要再次提交修正后的结果!!(再次提交很重要,切勿忘
记)
此时分支如下:
合并了分支后,不要忘记删了dev1分支。
分支小结:
分⽀在实际中有什么⽤呢?假设你准备开发⼀个新功能,但是需要两周才能完成,第⼀周你写了50%
的代码,如果⽴刻提交,由于代码还没写完,不完整的代码库会导致别⼈不能⼲活了。如果等代码全
部写完再⼀次提交,⼜存在丢失每天进度的巨⼤⻛险。
现在有了分⽀,就不⽤怕了。你创建了⼀个属于你⾃⼰的分⽀,别⼈看不到,还继续在原来的分⽀上
正常⼯作,⽽你在⾃⼰的分⽀上⼲活,想提交就提交,直到开发完毕后,再⼀次性合并到原来的分⽀
上,这样,既安全,⼜不影响别⼈⼯作。
并且 Git ⽆论创建、切换和删除分⽀,Git在1秒钟之内就能完成!⽆论你的版本库是1个⽂件还是1万个⽂件。
三、远程管理
理解分布式版本控制系统
理解分布式版本控制系统。
我们⽬前所说的所有内容(⼯作区,暂存区,版本库等等),都是在本地!也就是在你的笔记本或者
计算机上。⽽我们的 Git 其实是分布式版本控制系统!什么意思呢?
可以简单理解为,我们每个⼈的电脑上都是⼀个完整的版本库,这样你⼯作的时候,就不需要联⽹
了,因为版本库就在你⾃⼰的电脑上。既然每个⼈电脑上都有⼀个完整的版本库,那多个⼈如何协作
呢?⽐⽅说你在⾃⼰电脑上改了⽂件A,你的同事也在他的电脑上改了⽂件A,这时,你们俩之间只需
把各⾃的修改推送给对⽅,就可以互相看到对⽅的修改了。
分布式版本控制系统的安全性要⾼很多,因为每个⼈电脑⾥都有完整的版本库,某⼀个⼈的电脑坏掉
了不要紧,随便从其他⼈那⾥复制⼀个就可以了。
在实际使⽤分布式版本控制系统的时候,其实很少在两⼈之间的电脑上推送版本库的修改,因为可能
你们俩不在⼀个局域⽹内,两台电脑互相访问不了。也可能今天你的同事病了,他的电脑压根没有开
机。因此,分布式版本控制系统通常也有⼀台充当“中央服务器”的电脑,但这个服务器的作⽤仅仅
是⽤来⽅便“交换”⼤家的修改,没有它⼤家也⼀样⼲活,只是交换修改不⽅便⽽已。有了这个“中央服务器”的电脑,这样就不怕本地出现什么故障了(⽐如运⽓差,硬盘坏了,上⾯的所有东西全部
丢失,包括git的所有内容)
远程仓库
Git 是分布式版本控制系统,同⼀个 Git 仓库,可以分布到不同的机器上。怎么分布呢?最早,肯定只
有⼀台机器有⼀个原始版本库,此后,别的机器可以 “克隆” 这个原始版本库,⽽且每台机器的版本
库其实都是⼀样的,并没有主次之分。
你肯定会想,⾄少需要两台机器才能玩远程库不是?但是我只有⼀台电脑,怎么玩?
其实⼀台电脑上也是可以克隆多个版本库的,只要不在同⼀个⽬录下。不过,现实⽣活中是不会有⼈
这么傻的在⼀台电脑上搞⼏个远程库玩,因为⼀台电脑上搞⼏个远程库完全没有意义,⽽且硬盘挂了
会导致所有库都挂掉,所以我也不告诉你在⼀台电脑上怎么克隆多个仓库。
实际情况往往是这样,找⼀台电脑充当服务器的⻆⾊,每天24⼩时开机,其他每个⼈都从这个“服务
器”仓库克隆⼀份到⾃⼰的电脑上,并且各⾃把各⾃的提交推送到服务器仓库⾥,也从服务器仓库中
拉取别⼈的提交。
完全可以⾃⼰搭建⼀台运⾏ Git 的服务器,不过现阶段,为了学 Git 先搭个服务器绝对是⼩题⼤作。好
在这个世界上有个叫 GitHub 的神奇的⽹站,从名字就可以看出,这个⽹站就是提供 Git 仓库托管服务
的,所以,只要注册⼀个GitHub账号,就可以免费获得 Git 远程仓库。
具体创建git远程仓库的流程可以搜其他文章,这里只讲SSH协议和HTTPS协议克隆远程仓库到本地的区别。
SSH 协议和 HTTPS 协议是 Git 最常使⽤的两种数据传输协议。SSH 协议使⽤了公钥加密和公钥登陆机制,体现了其实⽤性和安全性,使⽤此协议需要将我们的公钥放上服务器,由 Git 服务器进⾏管理。使⽤ HTTPS ⽅式时,没有要求,可以直接克隆下来。
SSH协议添加公钥到远程仓库也可以搜教程。
向远程仓库推送
提交时要注意,如果我们之前设置过全局的 name 和 e-mail,这两项配置需要和 gitee 上配置的⽤⼾
名和邮箱⼀致,否则会出错。或者从来没有设置过全局的 name 和 e-mail,那么我们第⼀次提交时也
会报错。这就需要我们重新配置下了,同样要注意需要和 gitee 上配置的⽤⼾名和邮箱⼀致。如何配置已讲过,在这⾥就不再赘述。
到这⾥我们已经将内容提交⾄本地仓库中,如何将本地仓库的内容推送⾄远程仓库呢,需要使⽤ git
push 命令,该命令⽤于将本地的分⽀版本上传到远程并合并,命令格式如下:
git push 远程主机名 本地分支名:远程分支名
如果本地分支名和远程分支名相同,可以省略\":远程分支名\"
为:
git push 远程主机名 本地分支名
拉取远程仓库到本地
如果远程仓库的版本优先于本地仓库的代码版本,可以将远程仓库拉去到本地进行合并。
命令如下:
git pull 远程主机名 远程分支名:本地分支名
如果远程分支名和本地分支名一样,可以写成:
git pull 远程主机名 远程分支名
配置git文件
忽略特殊⽂件
在⽇常开发中,我们有些⽂件不想或者不应该提交到远端,⽐如保存了数据库密码的配置⽂件,那怎
么让 Git 知道呢?在 Git ⼯作区的根⽬录下创建⼀个特殊的 .gitignore ⽂件,然后把要忽略的⽂件
名填进去,Git 就会⾃动忽略这些⽂件了。
不需要从头写 .gitignore ⽂件,gitee 在创建仓库时就可以为我们⽣成,不过需要我们主动勾选⼀
下。
如果当时没有选择这个选择,在⼯作区创建⼀个也是可以的。⽆论哪种⽅式,最终都可以得到⼀个完
整的 .gitignore ⽂件,例如我们想忽略以 .so 和 .ini 结尾所有⽂件, .gitignore 的内容
如下:
# 其他内容...# My configurations:*.ini*.so
标签管理
标签 tag ,可以简单的理解为是对某次 commit 的⼀个标识,相当于起了⼀个别名。例如,在项⽬
发布某个版本的时候,针对最后⼀次 commit 起⼀个 v1.0 这样的标签来标识⾥程碑的意义。
创建标签
在Git中打标签⾮常简单,⾸先,切换到需要打标签的分⽀上。
然后,敲命令 git tag [name] 就可以打⼀个新标签:
git tag v1.0
可以用git tag命令查看所有标签。
默认标签是打在最新提交的 commit 上的。那如何在指定的commit上打标签呢?⽅法是找到历史提
交的commit id,然后打上就可以了
git tag v0.9 c6ce3f0(这个就是某个commit id号)
可以用git show + 标签 查看标签信息。
删除标签的命令也很简单:
git tag -d v1.0
因为创建的标签都只存储在本地,不会⾃动推送到远程。所以,打错的标签可以在本地安全删除。
如果要推送某个标签到远程,使⽤命令
git push origin tagname(标签名)
也可以一次性推送完标签到远程:git push origin --tags
如果标签已经推送到远程,并且想删除远程的标签,就麻烦一些:
1.先删除本地的标签
git tag -d v1.0
2.删除远程标签
git push origin :refs/tags/v1.0
注意要按照格式。
总结
本文讲了git的几乎所有常用操作。
关注我的微信公众号,直接免费答疑~