Git下载

Git官网下载地址:https://git-scm.com/download

Git配置

查看配置
git config -l

查看系统配置
git config --system -l
#在安装目录的etc文件目录下

查看全局配置
#在C盘的用户目录下
git config --global --list

用户配置
git config --global user.name "username" #名称 git config --global user.email "xxxxxxxxx@qq.com" #邮箱

初始化仓库

1
git init

克隆仓库

1
2
#克隆一个项目和它的整个代码历史(版本信息)
git clone [url]

Git文件操作

文件的4种状态

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

  • Untracked:未跟踪,此文件在文件夹中,但并没有加入到git仓库,不参与版本控制,通过 git add 状态变为Staged
  • Unmodify:文件已经入库,未修改,即版本库中的文件快照内容与文件夹中完全一致,这种类型的文件有两种去处,如果它被修改,而变为Modified,如果使用git rm 移出版本库,则成为Untracked文件。
  • Modified:文件已修改,仅仅是修改,并没有进行其他的操作,这个文件也有两个去处,通过git add可进入暂存staged状态,使用git checkout则丢弃修改过,返回到unmodify状态,这个git checkout即从库中取出文件,覆盖当前修改!
  • Staged:暂存状态,执行git commit则将修改同步到库中,这时库中的文件和本地文件又变为一致,文件为Unmodify状态,执行git reset HEAD filename取消暂存,文件状态改为Modified

在这里插入图片描述

工作区:就是电脑上看到的目录,比如目录下testgit里的文件(.git隐藏目录版本库除外)。或者以后需要再新建的目录文件等等都属于工作区范畴。

版本库(Repository):工作区有一个隐藏目录.git,这个不属于工作区,这是版本库。其中版本库里面存了很多东西,其中最重要的就是stage(暂存区)(或者叫index),还有Git为我们自动创建了第一个分支master,以及指向master的一个指针HEAD。

使用Git提交文件到版本库有两步:

第一步:是使用 git add 把文件添加进去,实际上就是把文件添加到暂存区。

第二步:使用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支上。

(这些都是在本地仓的操作)

在这里插入图片描述

查看文件状态

上面说文件有4种状态,通过如下命令可以查看到文件的状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#查看所有文件的状态
git satus

#查看指定文件的状态
git status [filename]

#查看文件的修改内容(add和commit后)
git diff [file]

#查看历史版本
git log
git log -pretty=oneline #仅查看历史提交注释

#版本回退
git reset --hard HEAD^ #回退到上个版本
git reset --head HEAD^^ #回退到上上个版本
git reset --hard HEAD~100 #回退到前100个版本

#查看文件内容
cat [file]

#获取历史版本号
git reflog

#恢复到指定版本
git reset --hard [版本号]

版本恢复:

在这里插入图片描述

通过上面的显示我们可以知道,增加内容3333333的版本号是 b8a7cf3.我们现在可以使用命令

git reset --hard b8a7cf3来恢复了。演示如下:

在这里插入图片描述

可以看到目前已经是最新的版本了。

提交文件

1
2
3
4
5
6
7
8
#提交修改到暂存区
git add . #当前目录下的所有文件
git add [file1][file2] #1个或多个文件
git add [dir] #指定目录下的所有文件

#提交暂存区中的内容到本地仓库中 -m 添加注释
git commit -m "[注释]"

撤销修改和删除文件

1
2
#丢弃工作区的修改
git restore -- [file]

两种情况如下:

  1. file自动修改后,还没有放到暂存区,使用 撤销修改就回到和版本库一模一样的状态。
  2. 另外一种是file已经放入暂存区了,接着又作了修改,撤销修改就回到添加暂存区后的状态。
1
2
#删除工作区的文件
rm [file]

这是有两种选择:

  1. git commit提交删除修改到版本库
  2. git restore-- [file]从版本库中恢复文件

远程仓库

前面已经介绍了本地仓库的基本操作和原理

接下来可以创建一个远程仓库可用来备份本地仓库

常用仓库可来自github或gitee

创建好远程仓库后,要将本地仓和远程仓连接同步,常用有ssh和https两种同步方式。

  • https:很简单基本不需要配置就可以使用,但是每次提交代码和下载代码时都需要输入用户名和密码。
  • ssh:需要客户端先生成一个密钥对,即一个公钥一个私钥。然后还需要把公钥放到github的服务器上。

何为SSH?

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

基于密钥的安全验证

使用ssh协议通信时,推荐使用基于密钥的验证方式。你必须为自己创建一对密匙,并把公用密匙放在需要访问的服务器上。 如果你要连接到SSH服务器上,客户端软件就会向服务器发出请求,请求用你的密匙进行安全验证。服务器收到请求之后,先在该服务器上你的主目录下寻找你的公用密匙,然后把它和你发送过来的公用密匙进行比较。 如果两个密匙一致,服务器就用公用密匙加密“质询”(challenge)并把它发送给客户端软件。 客户端软件收到“质询”之后就可以用你的私人密匙解密再把它发送给服务器。

ssh密钥生成

  1. 创建SSH Key。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果有的话,直接跳过此如下命令,如果没有的话,打开命令行,输入如下命令生命公钥和私钥:ssh-keygen -t rsa一路回车,默认配置。

image-20211130230919706

在用户主目录下生成了.ssh文件夹内包含id._rsa(私钥)和id_rsa.pub(公钥)文件

在gitee(或github)中添加公钥

将id_rsa.pub中的内容复制到上面

连接远程仓库

1. 若是在远程仓的基础上连接,直接拿远程仓库对应的ssh

image-20211201001348335

在本地想要建立仓库的位置打开bash输入如下命令即建立连接

1
2
#克隆远程仓并建立ssh连接
git clone [ssh]

2. 若是在本地仓的基础上连接

1
2
3
4
#初始化建立本地仓
git init
#连接远程仓
git remote add origin [ssh]

则首先在想要建立本地仓的位置初始化

若出现如下错误:

image-20211201003115438

则说明该本地仓已连接远程仓

可以执行如下命令先把连接断开再连接新的远程仓

1
git remote rm origin

同步本地仓版本到远程仓

1
git push -u origin master

若出现如下错误:

image-20211201003258509

则说明本地仓无远程仓的README.txt

则应先从远程仓拉取文件合并

1
2
#拉取文件合并
git pull --rebase origin master

把本地库的内容推送到远程,使用git push命令,实际上是把当前分支master推送到远程。

由于远程库是空的,我们第一次推送master分支时,加上了 –u 参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。

从现在起,只要本地作了提交,就可以通过如下命令:git push origin master

把本地master分支的最新修改推送到github上了,现在你就拥有了真正的分布式版本库了。

创建与合并分支

创建、切换分支

在版本回填退里,你已经知道,每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支。HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是当前分支。

首先,我们来创建dev分支,然后切换到dev分支上。如下操作:

image-20211201004122565

1
2
3
4
5
6
7
8
#切换分支
git checkout [分支名]

#创建并切换到分支
git checkout -b [分支名]

#查看当前分支并列出所有分支
git branch

我们接着在dev分支操作:

image-20211201004637593

切换回master分支会发现内容并未改变:

image-20211201004706854

这是因为这个改变仅是发生在dev分支的,这就方便了多人协作开发,每个人的分支不同,提交不影响其他人的版本。

合并分支

把dev分支上的内容合并到master分支上:

在master分支上执行如下命令:

1
2
#将指定分支合并到当前分支上
git merge [指定分支名]

image-20211201005158548

可看到,和dev分支最新提交的完全一样

注意到上面的Fast-forward信息,Git告诉我们,这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。

分支命令总结:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#查看分支
git branch

#创建分支
git branch [name]

#切换分支
git checkout [name]

#创建并切换分支
git checkout -b [name]

#合并指定分支到当前分支
git merge [name]

#删除分支
git branch -d [name]

冲突

dev分支提交新内容 4444444444

image-20211201010538476

master分支添加内容 55555555

image-20211201010906092

则此时在master合并dev会出现冲突:

image-20211201010923278

此时状态:

image-20211201011001979

Git用<<<<<<<=======>>>>>>>标记出不同分支的内容,其中<<<HEAD是指主分支修改的内容,>>>>>dev 是指dev上修改的内容,我们可以修改下如下后保存:

image-20211201011139584

则此时有两个分支的内容,自己调整即可:

image-20211201011348531

image-20211201012025041

查看分支合并情况

1
2
#查看分支合并情况
git log .

image-20211201011520361

分支管理策略

通常合并分支时,git一般使用"Fast forward"模式,在这种模式下,删除分支后,会丢掉分支信息,现在我们来使用带参数 –no-ff来禁用"Fast forward"模式。首先我们来做demo演示下:

  1. 切换到dev分支。
  2. 修改test.txt内容。
  3. 添加到暂存区。
  4. 切换回主分支(master)。
  5. 合并dev分支,使用命令 git merge –-no-ff -m [注释] dev
  6. 查看历史记录

image-20211201013239187

删除dev分支后版本仍在

image-20211201013426917

分支策略:首先master主分支应该是非常稳定的,也就是用来发布新版本,一般情况下不允许在上面干活,干活一般情况下在新建的dev分支上干活,干完后,比如上要发布,或者说dev分支代码稳定后可以合并到主分支master上来。

bug分支

在开发中,会经常遇到bug问题,那么有了bug就需要恢复,在Git中,分支是很强大的,每个bug都可以通过一个临时分支来修复,修复完成后,合并分支,然后将临时的分支删除掉。

比如在开发中接到一个404 bug时,我们可以创建一个404分支来修复它,但是,当前的dev分支上的工作还没有提交,且未完成dev分支上的工作。那么我们要放弃dev分支的工作或先暂放404的bug修复吗?

不然,Git提供了一个stash功能,可以把当前的工作现场“隐藏起来”,等以后恢复现场后继续工作git stash

image-20220206222711248

那么现在就可以创建issue-404分支来修复bug了。

首先我们要确定在哪个分支上修复bug,比如现在是在主分支master上修复的,现在就要在master分支上创建一个临时分支:

image-20220206224132971

修复完成后,切换到master分支上,并完成合并,最后删除issue-404分支:

image-20220206224436709

此时master分支上的内容和issue-404内容一致。

删除issue-404分支:

image-20220206224617996

现在,回到dev分支上继续干活!

image-20220206224752374

目前工作区状态是干净的。

可以使用git stash list查看:

image-20220206224858943

工作现场还在,Git把stash内容存在某个地方了,但是需要恢复一下,可以使用如下两个方法:

  • git stash apply:恢复后,stash内容并不删除,你需要使用命令git stash drop来删除。
  • git stash pop:恢复的同时把stash的内容也删除了。

演示:

image-20220206225305548

多人协作

当你从远程仓克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来,并且远程仓的默认名称为origin。

  • 要查看远程仓的信息,使用git remote
  • 要查看远程仓的详细信息,使用git remote -v

image-20220206230157192

推送分支

推送分支就是把该分支所有本地提交到远程仓中,推送时,要指定本地分支,这样,Git就会把该分支推送到远程仓对应的远程分支上:

比如我要推送本地仓master分支上的内容,目前远程仓上master分支的Test.txt内容如下:

image-20220206230940721

推送本地仓master分支上的内容,使用git push origin master命令:

image-20220206231155743

推送成功,此时远程仓master分支的Test.txt文件内容如下:

image-20220206231253425

而dev分支的内容是这样的:

image-20220206231442550

且本次推送并没有推送dev分支:

image-20220206231455668

若想推送dev分支的内容则执行命令git push origin dev:

image-20220206231736116

image-20220206231724186

成功将dev分支推送到远程仓!

注意:

  • master分支是主分支,因此要时刻与远程同步。
  • 一些修复bug的分支不需要推送到远程去,可以先合并到主分支,然后把主分支master推送到远程去。

抓取分支

多人协作时,大家都会忘master分支上推送各自的修改。现在我们可以模拟另外一个同事,可以在另一台电脑上(注意要把SSH Key添加到github或gitee上)或者在同一台电脑上另外一个目录克隆,新建一个目录名字叫Git_Test2

从远程仓克隆内容:

image-20220206232609439

将整个远程仓内容以文件夹的形式克隆到本地仓:

image-20220206232704163

如果要在dev分支上开发,就必须要把origin上的dev分支克隆本地,则使用命令创建本地dev分支:

1
git checkout -b dev origin/dev

image-20220207000445127

可以看到远程仓的dev分支上的内容已经被clone到本地了。

image-20220207000703067

image-20220207001830224

完成向origin/dev分支的推送。

而我们在目录文件下也对同样的文件的同个地方进行修改,也试图推送到远程仓时,如下:

image-20220207001217202

由于不同的人推同样的文件,修改同一个文件的同一个地方报错!解决的方法也很简单,上面提示我们,先用git pull把最新的提交从origin/dev抓下来,然后在本地合并,解决冲突,再推送。

image-20220207002048405

git pull成功了,但是合并有冲突,需要手动解决,解决的方法和分支管理中的解决冲突完全一样,解决后,提交,再push。

原Test.txt:

image-20220207002224069

手动解决后,在提交并push到远程仓:

image-20220207002820127

因此,多人协作工作模式一般是这样的:

  • 首先,可以试图用git push origin branch-name推送自己的修改。
  • 如果推送失败,则因为远程分支比你本地更新早,需要先用git pull试图合并。
  • 如果合并有冲突,则需要解决冲突,并在本地提交。再用git push origin branch-name推送。

Git 命令总结

基本命令

1
2
3
4
5
6
7
8
9
10
11
#清除面板内容
clear

#创建一个空目录 XX指目录名
mkdir XX

#显示当前目录的路径
pwd

#把当前的目录变成可以管理的git仓库,生成隐藏.git文件
git init

文件操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#查看XX文件内容
cat XX

#删除XX文件
git rm XX

#提交修改到暂存区
git add .#当前目录下的所有文件
git add [file1][file2]#1个或多个文件
git add [dir]#指定目录下的所有文件

#提交文件 –m 后面的是注释
git commit –m “XX”

#查看仓库状态
git status

#查看指定文件的状态
git status [filename]

#丢弃工作区的修改
git restore -- [file]

#查看历史版本
git log
git log -pretty=oneline#仅查看历史提交注释


#版本回退
git reset --hard HEAD^#回退到上个版本
git reset --head HEAD^^#回退到上上个版本
git reset --hard HEAD~100#回退到前100个版本

#查看历史记录的版本号id
git reflog

#恢复到指定版本
git reset --hard [版本号]

分支操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#查看分支
git branch

#创建分支
git branch [name]

#切换分支
git checkout [name]

#创建并切换分支
git checkout -b [name]

#合并指定分支到当前分支
git merge [name]

#合并分支禁用Fast forward模式
git merge –-no-ff -m "注释" [name]

#删除分支
git branch -d [name]

#查看分支合并情况
git log .

#查看XX文件修改了那些内容
git diff XX

#隐藏保护工作现场
git stash

#列出之前隐藏保护起来的工作内容
git stash list

#恢复工作现场但不删除stash内容
git stash apply

#恢复工作现场并删除stash内容
git stash pop

#删除一条stash内容
git stash drop

远程仓库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#本地生成ssh公钥和私钥
ssh-keygen -t rsa

#克隆远程仓并建立ssh连接
git clone [ssh]

#连接远程仓
git remote add origin [ssh]

#断开与远程仓的连接
git remote rm origin

#把当前master分支推送到远程库(第一次要用u以后不需要)
git push -u origin master

#将某一分支的内容推送到远程仓
git push origin [branch-name]

#从远程仓拉取文件合并
git pull --rebase origin master

#抓取远程仓文件合并
git pull

#查看远程仓的信息
git remote

#查看远程仓的详细信息
git remote -v

#将远程仓的某一分支克隆到本地仓并新建一个分支
git checkout –b [branch-name] origin/[bran]

补充

抓取命令git fetch [remote name] [branch name]

  • 抓取命令就是将远程仓里的更新都抓到本地,不会进行合并。
  • 如果不指定远端名称和分支名称,则抓取所有分支。

拉取命令git pull [remote name] [branch name]

  • 拉取命令就是将远程仓的修改更新拉倒本地并自动进行合并,等同于fetch + merge
  • 如果不指定远端名称和分至名称,则抓取所有并更新当前分支。

git pullgit pull --rebase的区别:

git pull = git fetch + git merge
git pull --rebase = git fetch + git rebase

所以两者区别主要是远程与本地代码的合并上:

git merge:将远端master的代码和本地的代码在新增的节点合并,之前的提交会分开显示。

git --rebase:将两个分支融合成一个线性的提交,不会形成新节点。

简单来讲就是正常的解决冲突过程是

  1. git add
  2. git commit -m "..."
  3. git push时因为本地仓库代码与远程仓代码有冲突,所以接下来
  4. git pull拉取远程代码,而冲突需要手动解决
  5. 解决好后重新进行

git add

git commit -m".."

git push

git pull这一步如果加上了--rebase的选项,那么第5步操作将变成如下

git add

git rebase --continue

git push

所以git pull --rebase用在合并代码的时候其作用就是在一个随机创建的分支上处理冲突,避免了直接污染原来的分区。

学习资料

【狂神说Java】Git最新教程通俗易懂

Git的安装与使用教程(超详细!!!)

黑马程序员Git全套教程,完整的git项目管理工具教程,一套精通git

git pull –rebase的理解