Git全面详解,深入了解Git(包含解决分支冲突,分支合并等)

一. Git简介

Git是一种代码托管技术。在开发中,Git是一种代码托管技术,很多代码托管平台也是基于Git来实现的。Git可以帮我们做到很多的事情,比如代码的版本控制,分支管理等。

注意:

我们可以把Git理解成是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。正是因为有了Git的存在,现在很多工作才可以变得相对轻松。

Git工作流程

四个工作区域

Workspace: 工作区,就是你平时存放项目代码的地方

Index / Stage: 暂存区也叫索引区,用于临时存放你的改动,事实上它只是一个文件,保存即将提交到文件列表信息

Repository: 仓库区(或版本库),就是安全存放数据的位置,这里面有你提交到所有版本的数据。其中HEAD指向最新放入仓库的版本

Remote: 远程仓库,托管代码的服务器,可以简单的认为是你项目组中的一台电脑用于远程数据交换

Git的工作流程一般是这样的:

  1. 在工作目录中添加、修改文件;
  2. 将需要进行版本管理的文件放入暂存区域;
  3. 将暂存区域的文件提交到git仓库。

二. Git配置

2.1 设置用户信息

1.全局配置用户姓名
git config --global user.name "xxx"

2.全局配置邮箱
git config --global user.email "xxx@xxx"

3.若要配置局部
git config --local user.name "xxx"
git config --local user.email "xxx@xxx"

2.2 查看配置信息

检查当前的设置

1.查看git的配置信息
git config --list

2.查看git配置的用户名.
git config user.name

注意:通过上面的命令设置的信息会保存在~/.gitconfig文件中。也就是用户目录下的.gitconfig.

三.初始化Git仓库

打开终端机窗口,并试着操作以下命令(命令后面的#是说明,不需要输入):

1.创建一个目录
mkdir tmp  #创建tmp目录
2.移动到此目录
cd tmp
3.初始化git仓库
git init   #初始化这个目录让Git对这个目录开始进行版本控制。

小提示:

git init 命令会在上述目录中创建一个名为 .git 的隐藏目录,并在其中创建一个版本库。该目录为文件,查看->显示隐藏目录。

四.文件的两种状态

版本控制就是对文件的版本控制,要对文件进行修改、提交等操作,首先要知道文件当前在什么状态,不然可能会提交了现在还不想提交的文件,或者要提交的文件没提交上。

注意:

Git不关心文件两个版本之间的具体差别,而是关心文件的整体是否有改变,若文件被改变,在添加提交时就生成文件新版本的快照,而判断文件整体是否改变的方法就是用SHA-1算法计算文件的校验和。

4.1 untracked未跟踪

未跟踪, 此文件在文件夹中, 但并没有加入到git库, 不参与版本控制. 通过git add 状态变为Staged.

4.2 tracked已跟踪

被纳入版本控制

  • Unmodified

文件已经入库, 未修改, 即版本库中的文件快照内容与文件夹中完全一致. 这种类型的文件有两种去处, 如果它被修改, 而变为Modified,如果使用git rm移出版本库, 则成为Untracked文件。

  • Modified

文件已修改, 仅仅是修改, 并没有进行其他的操作. 这个文件也有两个去处, 通过git add可进入暂存staged状态, 使用git checkout 则丢弃修改过,返回unmodify状态, 这个git checkout即从库中取出文件, 覆盖当前修改。

  • Staged

暂存状态. 执行git commit则将修改同步到库中, 这时库中的文件和本地文件又变为一致, 文件为Unmodify状态. 执行git reset HEAD filename取消暂存,文件状态为Modified。

注意:

这些文件的状态会随着我们执行Git的命令发生变化

注意:

  • 新建文件--->Untracked
  • 使用add命令将新建的文件加入到暂存区--->Staged
  • 使用commit命令将暂存区的文件提交到本地仓库--->Unmodified
  • 如果对Unmodified状态的文件进行修改---> modified
  • 如果对Unmodified状态的文件进行remove操作--->Untracked

4.3 查看文件状态命令

语法结构:

1.查看文件状态
git status

参数:

  • -s: 简洁输出

五.文件加入暂存区

5.1 文件加入暂存区命令

语法结构

1.将文件加入暂存区
git add 文件名

2.将当前目录下所有文件提交到暂存区.
git add .

5.2 文件取消暂存区命令

语法结构

1.将暂存区的文件变为untracked的状态.
git reset 文件名

六.文件提交与删除

如果仅是通过git add命令把移动加到暂存区,还不算是完成整个流程。如果想让暂存区的内容永久保存下来,就要使用git commit命令。

6.1 文件提交命令

语法结构:

1.提交到仓库
git commit -m "提交信息"

参数:

  • -m : 本次提交做了什么事,只要简单、清楚的文本说明即可,中英文都可以重点是说清楚,能让自己和别人很快明白就行。

如果不加m参数,会进入类似vim编辑。

6.2 修改commit记录

身为程序员,难免会遇到一些不太顺心的客户或项目。心情不好的时候,在代码或Commit信息中“发泄”一下情绪也是很常见的,只是这要是让客户看见了总是不好解释。

要改动Commit记录有几种方式。

  • (1)把.git目录整个删除(不建议)。
  • (2)使用git rebase命令来改动历史记录。
  • (3)先把 Commit用git reset命令删除,整理后再重新Commit。
  • (4)使用--amend参数改动最后一次的Commit。
6.2.1 使用--amend参数进行Commit
1.查看提交的日志.
git log --oneline

只需要在Commit命令后面加上--amend即可

1.修改最后一次提交后的信息.
git commit --amend  -m "index has commit"

6.3 Git基础_删除文件

语法结构:

1.删除文件
git rm 文件名

注意:

删除的文件只是删除工作目录的文件,我们的版本库里面还是存在的。 删除文件会把这个文件直接放入暂存区。

6.4 挽救已被删除的文件或目录

“人有失手,马有失蹄”,人总会有不小心或状态不好的时候。不管是有意还是无心 在Git中如果不小心把文件或目录删除了,是可以挽救回来的,这也是使用版本控制系统最主要的原因之一。

这里先使用rm命令,故意把项目中所有的HTML文档删除:

1.强制删除
rm -rf index.html

可以看出当前1个文件都处于被删除(deleted)状态。

可以使用git checkout命令:

git checkout index.html

注意:

当使用git checkout命令时,Git 会切换到指定的分支,但如果后面接的是文件名或路径,Git则不会切换分支,而是把文件从.git目录中复制一份到当前的工作目录。更精准地说,这个命令会把暂存区中的内容或文件拿来覆盖工作目录中。

如果想把所有删除文件都挽救回来,可以使用以下命令:

git checkout .

小技巧:

这个技巧不仅可以将删除的文件挽救回来,当改动某个文件后反悔了,也可以用它把文件恢复到上一次Commit的状态。不是所有情况下都能恢复被删除的文件的。因为整个Git的记录都是放在根目录下的 .git目录中,如果这个目录被删除了,也就意味着历史记录也被删除了,那么删除的文件也就不能恢复了。

6.4.1 挽救git rm的文件
git rm [文件名]

随后输入以下命令(git reset HEAD test1.txt 这个命令在 Git 版本控制系统中用于将指定文件(test1.txt)从暂存区(staging area 或 index)中撤销出来,但保留这个文件在工作目录(working directory)中的更改。)

git reset HEAD test1.txt

接着我们再checkout一下就可以啦

git checkout test1.txt

七.将文件添加至忽略列

一般我们总会有些文件无需纳入Git的管理,也不希望它们总出现在未跟踪文件列表。通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。在这种情况下,我们可以在工作目录中创建一个名为 .gitignore的文件(文件名称固定),列出要忽略的文件模式。

7.1忽略规则

# / 表示 当前文件所在的目录


# 忽略public下的所有目录及文件
/public/*

#不忽略/public/assets,就是特例的意思,assets文件不忽略
!/public/assets

# 忽略具体的文件
index.class

# 忽略所有的class
*.class


# 忽略 a.class b.class
[ab].class

注意:

  • #匹配规则和linux文件匹配一样
  • #以斜杠“/”开头表示目录
  • #以星号“*”通配多个字符
  • #以问号“?”通配单个字符
  • #以方括号“[]”包含单个字符的匹配列表
  • #以叹号“!”表示不忽略(跟踪)匹配到的文件或目录

八.日志记录操作

8.1 查看日志

语法结构:

git log

参数:

  • --graph : 查看分支合并图
  • --oneline : 标记把每一个提交压缩到了一行中

8.2 获取每一次提交执行的命令

语法结构:

git reflog

九. 比较文件差异

diff是指的是两个事物的不同。例如在Linux系统中,diff命令会逐行比较两个文本的差异然后显示出来。

9.1 git diff命令格式

语法结构:

git diff [--cached]

注意:

  • ---:标记原始文件
  • +++:标记新文件
  • @@:两个不同文件版本的上下文行号。
  • -: 原始文件删除改行
  • +:原始文件增加一行

9.2 实战演习

工作区与暂存区比较

git diff

把修改文件追加到暂存区

git add .

暂存区与仓库的比较

git diff --cached

十.还原文件

对于恢复修改的文件,就是将文件从仓库中拉到本地工作区,即 仓库区 ----> 暂存区 ----> 工作区。

对于修改的文件有三种情况:

  • 只是修改了文件,没有任何 Git 操作
  • 修改了文件,并提交到暂存区(即编辑之后,gitadd但没有gitadd但没有 git commit -m ....)
  • 修改了文件,并提交到仓库区(即编辑之后,gitadd和gitadd和 git commit -m ....)

情况I

只是修改了文件,没有任何 git 操作,直接一个命令就可回退

$ git checkout -- aaa.txt # aaa.txt为文件名

我们修改一下test1文件

然后执行下列语句.

情况II

修改了文件,并提交到暂存区(即编辑之后,git add但没有gitadd但没有 git commit )


$ git log --oneline   # 可以省略

$ git reset HEAD   # 回退到当前版本

$ git checkout -- aaa.txt   # aaa.txt为文件名

注意:

情况II 和 情况III 只有回退的版本不一样,对于 情况II,并没有 $ git commit,仓库版本也就不会更新和记录,所以回退的是当前版本

情况III

修改了文件,并提交到仓库区(即编辑之后git add和gitadd和 git commit -m )

$ git log --oneline   # 可以省略

$ git reset HEAD^   # 回退到上一个版本

$ git checkout -- aaa.txt   # aaa.txt为文件名

随后

注意:

git reset 版本号 ---- 将暂缓区回退到指定版本,根据 $ git log --oneline 显示的版本号,可以回退到任何一个版本,也可通过 HEAD 来指定版本。

  • HEAD 当前版本
  • HEAD^ 上一个版本
  • HEAD^^ 上上一个版本

十一. 常见远程仓库托管平台

十二. Git远程仓库操作

添加远程仓库

添加一个新的远程Git仓库,同时指定一个可以引用的简写。

语法结构:

git remote add <shortname><url>

注意:

  • shortname :远程的名字(可以随意取名)
  • url : 远程仓库地址

查看远程仓库

如果想查看已经配置的远程仓库服务器,可以运行git remote命令。它会列出指定的每一个远程服务器的简写。如果已经克隆了远程仓库,那么至少应该能看到origin,这是Git克隆的仓库服务器的默认名。

语法命令:

git remote

克隆远程仓库

如果你想获得一份已经存在了的Git仓库的拷贝,这时就要用到gitclone命令。Git克隆的是该Git仓库服务上的几乎所有数据(包括日志信息、历史记录等),而不仅仅是复制工作所需要的文件。当你执行git clone 命令的时候,默认配置下远程Git仓库中的每一个文件的每一个版本都将被拉取下来。

语法结构:

git clone 远程仓库地址url

移除无效的远程仓库

如果因为一些原因想要移除一个远程仓库,可以使用git remote rm

语法结构:

git remote rm  远程仓库名字

注意:此命令只是从本地移除远程仓库的记录,并不会真正影响到远程仓库。

推送至远程仓库

当你想分享你的代码时,可以将其推送到远程仓库。

语法结构:

git push [remote-name][branch-name]

从远程仓库中抓取与拉取

语法结构:

git fetch

注意:

git fetch是从远程仓库获取最新版本到本地仓库,不会自动merge,想看见文件就需要手动进行合并文件 git merge origin/master 。

从远程仓库中抓取与拉取

语法结构:

git pull

注意:

git pull是从远程仓库获取最新版本到本地仓库,会自动merge

十三. Git远程仓库_多人协作冲突问题

为什么会出现冲突问题

  1. 不同分支下的合并
  2. 同一个分支下的pull后者push

报错:

$ git push To https://gitee.com/xxx.git [rejected] master -> master (fetch first) error: failed to push some refs to 'kalista/百战' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.

解决冲突

拉取最新的代码

git pull

查看哪里冲突

new
<<<<<<< HEAD
#你自己写的
this is myself
=======
#别人写的并且提交了的代码
public class HelloWorld{}
>>>>>>> 0b8b926afc79bd22d220bd0cb76ef7d97b5fb5d4

注意:

手动删除不要的代码。

重新提交

git commit -am"修改了信息"

git push

十四. Git分支__使用分支原因

几乎所有的版本控制系统都以某种形式支持分支。使用分支意味着你可以把你的工作从开发主线上分离开来,以免影响开发主线。

查看分支

列出版本库中的分支名。

语法结构:

git branch

参数:

  • -r : 列出所有远程分支
  • -a :列出所有本地分支和远程分支

创建分支

语法结构:

git branch 分支名字

git branch -m [原名] [修改的名字]

参数:

  • -m 修改分支名字

切换分支

语法结构:

git checkout [分支名]

Git分支_推送至远程仓库分支

语法结构:

git push 远程仓库名字  分支名字

注意: 只有从git push 到远程仓库后,远程仓库才会出现对应的分支.在远程仓库创建分支,本地是获取不了的.只有推送过后才能获取.

十五. Git分支_合并分支

15.1 对分支的误解

有人可能认为,所谓的“开分支”,就是把文件先复制到另外的目录,然后进行改动,之后再合并,把文件与原本的文件比对之后放回原来的目录……其实,Git不是这样做的。

分支像贴纸一样

可以把分支想象成一张贴纸,贴在某一个Commit上面。

当做了一次新的Commit之后,这个新的Commit会指向它的前一个Commit。

而接下来“当前的分支”,也就是HEAD所指的这个分支,会贴到刚刚做的那个Commit 上,同时HEAD也会跟着前进。

结论:

Git中的分支并不是通过复制目录或文件来进行改动形成的,它就是一个指标、一张贴纸,贴在某个Commit 上而已。

一个分支不够,就来两个

如果一个分支不够说明,那就来两个。通过git branch cat命令创建一个新的分支。它就像一张贴纸,与master贴在同一个地方。

接下来执行git checkout cat命令,切换到cat分支。此时, HEAD转而指向cat分支,表示它是“当前的分支”。

接着进行一次新的Commit,这个新的Commit会指向前一次Commit。

然后,cat分支上的“贴纸”就会被撕下来,转而贴到最新的那个Commit上;当然HEAD也是一样。

合并分支

语法结构:(意义: 也就是将需要合并的分支名的部分)

git merge [需要合并的分支名]

切换分支Git干了什么

主要做两件事

  1. 更新暂存区和工作目录
  2. 变更HEAD的位置

合并过的分支要保留吗

合并后,原本没有的内容都有了,而分支本身又像一张贴纸一样“地位低微”,那么它也就没有利用价值了。所以,合并过的分支想删就删吧。

十六. Git分支_删除分支

删除本地仓库分支

语法结构:

git branch -d b1

参数:

  • -d 删除本地分支

注意:如果要删除的分支中进行了一些开发动作,此时执行上面的删除命令并不会删除分支,如果坚持要删除此分支,可以将命令中的-d参数改为-D 。

不小心把还没合并的分支删除了,救得回来吗

合并过的分支想留就留、想删就删,Git的分支并不是复制文件到某个目录,所以不会因为删掉分支文件就不见了。

注意:

但如果删除的是还未合并的分支就不一样了。

cat分支是从master分支出去的,当前领先master分支两次 Commit,而且还没有合并过。这时如果试着删掉cat分支,它会提醒:"这个分支还没全部合并哦"。

$ git branch -d cat

error: The branch 'cat' is not fully merged.
If you are sure you want to delete it, run 'git branch -D cat'.

虽然Git这么贴心的提醒了,但这里仍然把它删除了

git branch -D cat

Deleted branch cat(was b1729234)

上面不是已经删除cat分支了吗,怎么还在?这里再次跟大家说明一下分支的概念:分支只是一个指向某个Commit的指标,删除这个指标并不会使那些Commit消失。

git branch new_cat b2323b

注意:

这个命令"请帮我创建一个叫做new_cat的分支,让它指向17b23n3这个Commit",也就是在拿一张贴纸贴回去。

git branch

切换过去看看

git checkout new_cat

确认一下文件列表

1
ls -al

删除远程仓库分支

语法结构:

1
git push origin -d 分支名字

十七. Git标签_标签概念

标签是什么

Git可以给历史中的某一个提交打上标签,以示重要。比较有代表性的是人们会使用这个功能来标记发布结点(v1.0、v1.2等)。标签指的是某个分支某个特定时间点的状态。通过标签,可以很方便的切换到标记时的状态。

什么时候用标签

通常开发软件时会完成特定的“里程碑”,如软件版号1.0.0或beta-release之类的,这时就很适合使用标签做标记。

标签与分支有什么区别

标签与分支的区别是,分支会随着Commit而移动,但标签不会。之前介绍过当Git往前推,进一个Commit时,它所在的分支会跟着向前移动。而标签一旦贴上去不管Commit怎么前进,标签都会留在原来贴的那个位置上。因此,分支可以看成是“会移动的标签”。

注意:

这两者在被删除的时候,都不会影响到被指到的那个对象。

十八.Git标签_标签基本操作

列出已有标签

语法结构:

git tag

创建标签

语法结构:

git tag [标签名字]

查看标签信息

语法结构:

git show [标签名]

语法结构:

git push [remote] [tag]
remote: 远程仓库名
tag: 标签名
举例:
git push origin v1.0

十九. Git标签_检出与删除标签

检出标签

新建一个分支,指向某个tag

git checkout -b [branch] [tag]

删除标签

删除本地标签

语法结构:

git tag -d [tag]
删除远程标签

语法结构:

$ git push [远程仓库名] :refs/tags/标签名字

注意:

:refs/tags/是固定写法。(与远程仓库名之间有一个空格)

二十. Git支持的传输协议

由于Git的远程仓库不在我们本地,当我们在使用远程仓库的时候(例如克隆,拉取,推送)就会涉及到数据的网络传输,Git支持多种数据传输协议,包括:

  • 本地协议(Local)
  • HTTPS协议
  • SSH(Secure Shell)协议
  • Git协议

什么是SSH协议

SSH为Secure Shell(安全外壳协议)的缩写,由IETF的网络小组(Network Working Group)所制定。SSH是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用SSH协议可以有效防止远程管理过程中的信息泄露问题。

配置SSH协议

以使用Git提供的命令行工具Git Bash生成公钥和私钥,具体操作过程如下:

1.使用命令ssh-keygen -t rsa生成公钥和私钥

ssh-keygen -t rsa

注意:执行完成后在window本地用户.ssh目录(C:\Users\用户名.ssh)下生成如下名称的公钥和私钥。

2.复制公钥文件内容至服务器上

3.配置完成后就可以正常传输数据了

  • 16
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值