版本控制器之Git理论与实战

1.创建git本地仓库:git init

2.配置git

(1)设置用户名:git config [--global] user.name "your name"(加上--global选项表示这个机器上的所有仓库都会使用这个配置)

(2)查看配置:git config -l

(3)设置e-mail地址(一定是要真实的):git config [--global] user.email "你的邮箱"

(4)删除对应的配置:git config [--global] --unset 对应的配置

3.认识工作区,暂存区,版本库

(1)工作区:写代码的文件/目录或者其他文件的目录

(2)暂存区(stage/index):一般存在./git/index中,可以把暂存区称为索引

(3)版本库:.git目录就是版本库,版本库里面所有文件都能被git管理起来

三者关系

注意:通过新建/粘贴进目录的文件,只是存储在了工作区中,必须要通过git add或者git commit指令才能添加到仓库中进行管理。

4.查看提交日志:git log(显示从最近到最远的commit时的日志消息)

可以加上--pretty=oneline参数进行格式化输出日志

5.查看.git目录结构

默认的master分支:./git/refs/heads/master

6.修改文件

(1)查看当前仓库的状态

git status(用于查看你上次提交之后是否有对文件进行再次修改)

(2)查看被修改的文件内容

git diff 文件名(用来显示暂存区和工作区文件的区别)

git diff HEAD -- 文件名(查看版本库和工作区文件的区别)

7.版本回退

(1)git reset [--soft] [--mixed] [--head] [HEAD]

(2)git reflog(记录本地每一次命令)

从版本三回退到版本一

从版本一回退到版本三

(3)refs/heads/master文件保存当前master分支的最新commit id

当我们回退版本时,只是修改HEAD指针的指向

8.撤销修改

(1)工作区撤销修改:git checkout -- [file]

工作区撤销修改(直接删除代码),但是当我们写了很多代码时,难道我们还要花很多时间去删除我们写的代码吗,万一在我们删除的过程中搞出了BUG,那不炸了吗?

所以git为了解决这个问题,推出了一个指令

(2)暂存区中撤销修改:

先使用git reset --mixed HEAD [file]将工作区的修改进行回退到上一个版本

再使用git checkout -- [file]撤销工作区的内容

(3)在版本库中撤销修改

9.删除文件

(1)第一种情况:当我们不小心将工作区的文件删除了,由于删除也是一种修改,那么我们可以撤销修改

(2)第二种情况:当我们确定从版本库中删除一个文件时,那么该如何操作呢?

先在工作区和暂存区中删除文件,git rm filename

然后再进行提交

10.分支管理

(1)什么是分支

(2)创建分支(*表示HEAD指向的分支)

新创建的分支dev和master分支指向同一个修改

(3)切换分支:git checkout 分支名

git chekout 分支名

(4)合并分支:需要将dev分支合并到master分支,那么就不能在dev分支上进行合并,而是切换到master分支上进行合并。

git merge 分支名

(5)删除分支:如果当前正处于dev分支下,那么就不能删除dev分支

git branch -d 分支名

11.合并冲突

(1)创建并切换分支:git checkout -b 分支名

当出现合并冲突时,要手动解决冲突并再次提交

12.分支管理策略

(1)当处于Fast forward模式下,删除分支后,查看分支历史信息时,会丢掉分支信息,看不出最新分支是合并的分支还是正常提交的。

(2)当我们合并冲突时,解决冲突问题后,会在进行一次新的提交,即使我们删除了dev1分支,但是我们还是可以看出master分支是由其他分支进行合并的。

禁用Fast forward模式进行合并分支(禁用Fast forward模式时会创建一个新提交)

git merge --no-ff -m "merge with no-ff" dev2

(3)BUG分支

假设现在我们正在dev2分支下进行开发,但是开发到一半发现master分支上有BUG,需要解决(每一个BUG都可以创建一个临时的分支进行解决,解决后再合并分支,最后将临时分支进行删除)

但是现在dev2分支开发到一半还不能提交,那怎么办呢?

git stash可以将当前工作区信息进行储藏,被储藏的内容可以在将来的某个时间恢复出来。

git stash list:查看工作现场存储到哪里去了

git stash pop表示恢复工作现场,同时也把stash删除了

当我们修复了master分支的BUG时,我们需要将BUG分支合并到master分支中,如果我们直接在master分支上合并

BUG分支,会导致在master分支上出现冲突,容易给master分支修改错。

解决方法:在自己分支上先进行合并master分支,如果有冲突在自己分支上解决,解决了再让master分支进行合并自己的分支

13.删除临时分支

当我们在企业中开发时,每添加一个功能都会创建一个新分支,把这个分支叫做feature分支。

但是今天在feature分支上开发了一半,被产品经理叫停了,所以要销毁开发到一半的feature分支

常规的git branch -d 分支名是删除不了的,可以换成git brach -D 分支名

13.远程操作

在上面的内容都是基于本地进行的,也就是在我们计算机上,但是Git是分布式版本控制系统

什么是分布式版本控制系统呢,分布式控制系统通常有一台充当"中央服务器"的主机,但这个主机只是用来方便大家修改。那么有了它即使本地出现故障了,我们也可以直接从中央服务器哪里进行拉取内容。

(1)远程仓库

什么是远程仓库,就是使用一台24小时开机的服务器充当,比较出名的就是GitHub/gitee

(2)新建远程仓库

新建远程项目仓库

填写信息

创建成功

对远程仓库进行设置:开源or私有

刚建的仓库默认只有master分支

(3)本地克隆远端仓库

git clone 远程仓库链接

可以使用SSH,也可以使用HTTPS进行克隆,使用SSH需要将我们的公钥放到服务器上,有Git服务器进行管理

HTTPS就没有什么要求,可以直接clone

演示一下如何使用SSH进行clone

(1)先创建SSH Key

如果成功,就可以在用户主目录中找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件

id_rsa是密钥(不要泄漏给别人),id_rsa.pub是公钥(随便告诉)

(2)添加自己的公钥到远端仓库

点击ssh公钥进行设置

然后就可以clone了

(3)查看远程仓库(远程主机默认名称是origin)

git remote -v(-v显示详细信息)

(4)向远程仓库推送文件(在本地配置的邮箱和用户名要和远端的邮箱和用户名要一样)

git三板斧:

git add .(提交当前所有修改)

git commit -m "修改日志(认真填写)"

git push <主机名> <本地分支名>:<远程分支名>(将本地分支推送到远程并合并)

Git push <主机名> <本地分支名>(当远程分支名和本地分支名一样)

(5)拉取远程仓库

git pull <远程主机名> <远程分支名>:<本地分支名>

git pull <远程主机名> <远程分支名>(如果远程分支和当前分支合并)

14.配置Git

在日常开发中,我们有些文件不想或者不应该提交到远端,例如保存了数据库的密码的配置文件

那么如何让Git忽略这些文件呢?

在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件填进去,Git就自动忽略这些文件了。

那么这个.gitignore文件是要我们自己创建吗?

当然不是,gitee在创建仓库的时就会为我们自动生成,我们只需要勾选一下就行

当然我们也可以自己在本地创建一个.gitignore文件

现在我们在.gitignore文件中写入*.so和*.ini,表示我们需要忽略这两种文件

现在我已经将.gitgnore文件push到我的远端仓库了,现在我要验证当我在

工作区中添加.so和.ini文件时,git status会不会显示添加文件,不会就证明忽略成功了

所以我们的.gitignore文件生效了.

但是可能还有一种情况,就是我想添加到一个文件到Git中,但是这个文件被.gitignore忽略了,根本添加不了

我们可以使用git add -f filename来进行添加

但是也可能是我们的.gitignore文件写的有问题,那么可以使用git check-ignore指令进行检查

git告诉了我们,.gitignore的第二行忽略了该文件,所以我们就可以知道修改那个规则了。

还有一种情况,假设我们需要git忽略以.开头的部分隐藏文件,我们在.gitignore写了.*

那就尴尬了,*.也将我们的.gitignore文件也忽略了,这个时候我们可以在.gitignore文件

中添加一条例外规则

!.gitignore #表示不忽略.gitignore文件

15.给指令配置别名

在你使用git时候,有时候你会觉得指令实在太长了,让人敲的头疼,所以git推出了指令简化

git config --global alias.简化后的指令 被简化的指令(--global表示全局参数,也就是在当前主机下的所有仓库都适用,如果不加只是当前仓库适用)

现在我需要将git log --pretty=oneline简化成git olog

当然,初学者还是不建议使用这个,等我们工作了用熟悉了再进行简化我们的工作

16.标签管理

(1)标签定义

标签tar,可以理解为对某次的commit的一个标识,相当于给这次的commit起了一个别名

我们知道commit是用很长的commid id来标识了,现在出现了标签就可以让人很容易记录了commit的版本,当我们想要回退到那个版本时,直接使用标签就可以很快定位了。

(2)操作标签

在创建一个新标签之前,我们先切换到需要打标签的分支上,现在我需要在master分支上打标签

打标签:git tag -a 标签名 -m "标签说明" commit_id(也可以使用git tag 标签名)

默认的标签是打在最新提交的commit上的,那么如何给指定的commit打上标签呢?

找到commid id就行了

查看所有标签:git tag(标签不是按时间进行排序的,而是按字母进行排序)

查看单个标签详细信息

删除标签

现在我需要删除v0.9这个标签

由于我们创建的标签都是存储在本地,不会自动推送到远程,所以打错的标签可以直接在本地删除,

但是如果我们想要推送某个标签到远程

git push 远程主机名 标签名

如果本地有多个标签,也可以一次性全部推送

当我们的标签已经推送到远端了,那么我们该如何删除呢?

(1)先从本地删除

再从远端删除

17.多人协作开发(重要)

(1)多人协作开发一(多个人在同一个分支下进行开发)

现在我已经在Linux上clone下我的项目仓库了,然后我会在windows下clone同一个项目仓库模拟另一个开发者

如果没有windows版本的git,可以先去安装,直接上网搜就有了

在windows上先创建一个存放项目文件的目录.git,再右键点击该目录,打开git bash here

然后将远端仓库克隆下来

注意我这里只是模拟了两个用户,实际中每一个用户都有自己的gitee/github账号的,如果要进行多人协作开发,需要将用户添加进开发者,用户才有权限进行提交代码

现在准备工作已经完成,但是我们的远端仓库只有一个master主分支,在实际中,任何情况下都是不能直接在master分支上进行修改代码的,这个是为了保持主分支的稳定性,所以在我们开发新功能时,需要建立新的分支。

既然我们创建远程分支成功了,我们就需要拉取到本地

拉取分支完成了,现在我们要切换到dev分支了,但是有一个问题我们切换分支是切换本地的,那么如何切换远程的呢?我们可以将本地分支和远程分支进行关系链接:git checkout -b dev origin/dev

有老铁就会好奇,为什么在Linux上需要重新创建一个本地的dev分支,在windows上确不需要重新创建

这个是由于Git2.23+版本智能切换功能,当git发现你的本地没有dev分支,但在远程中存在/origin/dev分支,且分支名完全匹配,那么就会自动帮你在本地创建dev分支并和远程的dev分支建立关系链接。

到这里为止,你就可以愉快的和你的小伙伴进行开发了。

现在我要在dev上进行一次开发,并push到远程

那么我们来看看码云上的仓库状态

那么我们的代码就推送到了码云上

假设现在你的小伙伴要和你协同开发,碰巧也要对file.txt进行修改,并推送

但是推送失败了,你和你的小伙伴提交出现冲突了,那么如何解决呢?

git已经提示我们了,先git pull把最新提交从origin/dev上抓下来,然后再本地进行合并,并解决冲突,再进行push

冲突已解决,重新提交推送

看看码云上面是否有我们的提交

现在我们的代码已经提交到远端的dev分支上了,但是我们的最终的目的是将开发后的代码合并到master主分支上

让我们的项目运行最新的代码

在本地master分支进行合并dev分支之前先将远端master分支进行pull一下,保证本地的master是最新的内容。

然后再切换到dev分支上,合并master分支,这么做是为了当dev分支和master分支有冲突时,可以在dev分支上进行解决,而不是直接在master分支上解决

最后将本地master分支推送至远端

查看远端仓库验证一下

(2)多人协作开发二(多个人在不同分支下进行开发)

一般而言,是不会在同一个分支下进行多人开发的,而是一个需求或者功能点就要创建一个feature分支

现在假设有两个需求,你和你的小伙伴需要分别开发一个需求,所以你和你的小伙伴都要建立自己的feature分支

在上面我们已经知道了在码云上创建远程分支,那么这次我会从本地创建分支,然后再推送到远端

先在本地创建feature-1分支,再创建function1文件,将该文件进行提交和push

下面到你的小伙伴进行开发了

到这里我们就可以看出多人在不同分支开发的好处了,在本地他看不见你的,你看不见他的,所以根本不用担心冲突问题,你们互不影响

看看码云上状态

现在你们就可以在自己的分支上进行专业的开发了

但是突然有一天你的小伙伴生病请假了,但是他的需求还没开发完,需要你帮他开发,于是他把他的分支名

feature-2告诉你,所以你接下来就需要在你的机器上切换到feature-2分支进行开发

先将远端f仓库拉取下来

在本地创建feature-2分支和远端feature-2分支进行关系链接,并切换到feature-2分支上

所以在本地就出现了function2文件了,下面你就可以愉快的帮你的小伙伴进行开发了

看看远程状态

过了几天,你的小伙伴回来了,那么他就需要先获取到你帮他开发的内容,接着你的开发,或者你开发完了他也要看一下你写的代码

那是为什么呢?

是由于你的小伙伴没有指明本地feature-2和远程feature-2的链接,git已经给出提示了

现在你和你的小伙伴在各自的分支下开发完毕了,所以都需要合并到master分支上了。

由于你的小伙伴先开发完,那么他先开始merge

还是老习惯,先切换到master分支下进行pull,然后切换到feature-2分支下进行merge,最后切换到master分支下进行marge,最后将master进行push

看看远程仓库

当你的小伙伴的代码push了,你的开发也完成了,也要进行merge操作

也是老习惯,先切换到master分支下进行pull,然后切换到feature-1分支下进行merge,这时候,feature-1可能解决了冲突,feature-1有了新内容,为了保证远程分支是最新的,所以最好push一下,为什么呢?

因为在实际开发中master的merge操作一般不是由我们在本地进行操作,其他人员操作的时候,肯定是先pull远程的master分支,最后切换到master分支下进行marge,最后将master进行push(如果merge时有冲突,不要忘记commit才能push)

看看远程仓库

到这里就合并成功了,那么功能开发完毕了,feature-1和feature-2分支对我们没用了,可以在远程中删除了

然后我们在本地查一下看看远程分支是否删除了

我们看到远程的还存在,不要慌,这个只是记录而已,把记录删除就行了

git remote prune origin (将远端不存在的分支进行删除)

然后再删除本地分支

相关推荐
宇宙第一小趴菜4 小时前
11 安装回忆相册
linux·运维·centos7·yum·回忆相册·kh_mod
艾莉丝努力练剑4 小时前
【Linux指令 (二)】不止于入门:探索Linux系统核心与指令的深层逻辑,理解Linux系统理论核心概念与基础指令
linux·服务器·数据结构·c++·centos
conkl4 小时前
Linux IP 网络配置与管理详解
linux·网络·tcp/ip
kingg5 小时前
【征文计划】基于 Rokid JSAR 的 2D 粒子画廊实现:从技术概述到核心代码解析
github
绝无仅有5 小时前
面试真实经历某商银行大厂Java问题和答案总结(一)
后端·面试·github
绝无仅有5 小时前
面试真实经历某商银行大厂Java问题和答案总结(二)
后端·面试·github
ZhiqianXia5 小时前
Linux 内核中控制调试输出的频率和次数
linux
星源~5 小时前
Linux-Ubuntu系统安装特别指导
linux·qt·ubuntu·嵌入式开发·物联网设备
读书读傻了哟5 小时前
Windows 10 使用 VMware Workstation 搭建 Ubuntu 虚拟机
linux·windows·ubuntu