Git 概念

tanqi
12
2025-04-21

分布式版本控制系统Git

第1章 Git概述

1.1 何为版本控制(Version Control)

版本控制是一种记录文件内容变化,以便将来查阅特定版本修订情况的系统。

版本控制其实最重要的是可以记录文件修改历史记录,从而让用户能够查看历史版本,方便版本切换。无论对于个人、团队开发,版本控制都很有必要。

这种原始的版本管理系统很显然有明显的缺陷:

²  文件大量冗余,占用空间多,尤其是文件本身很大,但差异很小,问题更严重

²  从文件名看不出各个版本的差异之处,不易找出某个需要的历史版本

为了有效的解决版本控制问题,版本控制系统应运而生。

1.2 为什么需要版本控制

无论个人开发还是团队协作开发,都需要版本控制,尤其是团队协作开发。

1.3 版本控制系统

1)   本地版本控制系统

记录文件每次的更新,可以对每个版本做一个快照,或是记录补丁文件,适合个人用,如RCS。

缺点:适合个人使用,不适合团队协同开发;版本库只有一份,容易出现单点故障,会丢失历史版本。

2)   集中版本控制系统

集中化的版本控制系统诸如 CVS、SVN等,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。多年以来,这已成为版本控制系统的标准做法。

这种做法带来了许多好处,每个人都可以在一定程度上看到项目中的其他人正在做些什么。而管理员也可以轻松掌控每个开发者的权限,并且管理一个集中化的版本控制系统,要远比在各个客户端上维护本地数据库来得轻松容易。

缺点:

²  版本库只有一份,单点故障问题没有解决;

²  必须联网才能工作,如果不连网或者服务器宕机,用户无法下载和提交代码,看不到历史版本等。 

3)   分布式版本控制系统

除需一个版本控制服务器作为远程仓库存储历史版本记录外,服务器的所有版本信息全部同步到每个用户机器的本地库上,比如GIT、Mercurial、Bazaar、Darcs等。

这样就可以在本地查看所有版本历史,可以离线在本地提交,只需在连网时 push 到相应的服务器或其他用户那里。

由于每个用户那里保存的都是所有的版本数据,只要有一个用户的设备没有问题就可以恢复所有的数据,当然这增加了本地存储空间的占用。

集中式版本控制一直是多少年来的标准版本控制方法。分布式版本控制系统是对集中式版本控制系统的一次补充和完善,越来越多的被使用。

分布式的版本控制系统出现之后,解决了集中式版本控制系统的缺陷:

²  服务器断网的情况下也可以进行开发(因为版本控制是在本地进行的)

²  每个客户端保存的也都是整个完整的项目(包含历史记录,更加安全)

1.4 Git简史

Git是目前世界上最先进的分布式版本控制系统

BitKeeperBitMover公司开发,该公司CEO Larry McVoyLinus曾是好友, Larry说服Linus在内核开发中使用BitKeeper。而BitKeeper在免费使用的许可证中加入很多限制条件,惹恼了内核开发者,最终促使Linus开发出了毁灭BitMoverGitLinus 是在BitKeeper停止向开源社区提供免费版本后开发了Git,今天Git和其它自由软件版本控制系统已经统治了编程社区,BitKeeper变得无关紧要了。

1.5 Git代码托管中心

代码托管中心是基于网络服务器的远程代码仓库,一般我们简单称为远程库

GitHub:世界上最大的同性交友网站,技术宅男的天堂,新世界的大门。 http://www.github.com

码云(gitee):世界上第二大的同性交友网站  https://gitee.com/

深圳市奥思网络科技有限公司( OSCHINA ),通过 社区 Gitee(码云) 众包 等产品支持开源生态环境。

1.6 Git本地工作机制

第2章 Git安装

              官网地址: https://git-scm.com/https://github.com/git-for-windows/git/releases

下载地址:https://git-for-windows.github.io/   

              查看GNU协议,可以直接点击下一步。

选择Git安装位置,要求是非中文并且没有空格的目录,然后下一步。

Git选项配置,推荐默认设置,然后下一步。

Git安装目录名,不用修改,直接点击下一步。

Git的默认编辑器,建议使用默认的Vim编辑器,然后点击下一步。

默认分支名设置,选择让Git决定,分支名默认为master,下一步。

修改Git的环境变量,选第一个,不修改环境变量,只在Git Bash里使用Git

选择后台客户端连接协议,选默认值OpenSSL,然后下一步。

配置Git文件的行末换行符,Windows使用CRLFLinux使用LF,选择第一个自动转换,然后继续下一步。

选择Git终端类型,选择默认的Git Bash终端,然后继续下一步。

选择Git pull合并的模式,选择默认,然后下一步。

选择Git的凭据管理器,选择默认的跨平台的凭据管理器,然后下一步。

其他配置,选择默认设置,然后下一步。

实验室功能,技术还不成熟,有已知的bug,不要勾选,然后点击右下角的Install按钮,开始安装Git。

点击Finsh按钮,Git安装成功!

安装完成后,在任意的文件目录下,右键选择Git Bash Here,都可以开打Git的命令行窗口

在Git Bash终端里输入git --version查看git版本,如图所示,说明Git安装成功。

第3章 Git常用命令

Git常用命令

命令名称

作用

git config --global user.name 用户名

设置用户签名

git config --global user.email 邮箱

设置用户签名

git init

初始化本地库

git status

查看工作区和暂存区状态

git add 文件名

添加到暂存区

git commit -m "日志信息" 文件名

提交到本地库

git reflog/ git log

查看历史记录

git reset --hard 版本号

版本穿梭

3.1 设置用户签名

1)基本语法

git config --global user.name 用户名

git config --global user.email 邮箱

2)案例实操

全局范围的签名设置:

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git config --global user.name Layne

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git config --global user.email Layne@qiqi.com

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ cat ~/.gitconfig

[user]

   name = Layne

   email = Layne@qiqi.com

说明:

签名的作用是区分不同操作者身份。用户的签名信息在每一个版本的提交信息中能够看到,以此确认本次提交是谁做的。Git首次安装必须设置一下用户签名,否则无法提交代码。

²  --global 表示全局属性,所有的git项目都会共用属性

²  查看配置信息:git config --list

²  在当前登录的系统用户路径下,生成~/.gitconfig文件,里面可以看到刚刚设置的信息。如果不用命令设置,也可以直接打开文件进行设置。

※注意:这里设置用户签名和将来登录GitHub(或其他代码托管中心)的账号没有任何关系。

3.2 初始化本地库

1)基本语法

git init

2)案例实操

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720

$ git init

Initialized empty Git repository in D:/Git-Space/SH0720/.git/

 

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ ll -a

total 4

drwxr-xr-x 1 Layne 197609 0 11月 25 14:07 ./

drwxr-xr-x 1 Layne 197609 0 11月 25 14:07 ../

drwxr-xr-x 1 Layne 197609 0 11月 25 14:07 .git/   .git 初始化的效果,生成git

3)结果查看

注意:当前的 .git 是一个隐藏文件夹,需要在电脑上面设置隐藏文件夹显示设置,否则,看不到这个.git目录

再次理解工作区、版本库、暂存区概念

l  工作区(Working Directory):就是你电脑本地硬盘目录,一般是项目当前目录

l  暂存区(stage):一般存放在"git目录"下的index文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)

l  版本库(本地库Repository):工作区有个隐藏目录.git,它就是Git的本地版本库

l  分支(BranchGit为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD

提交Git本地版本库分两步执行

第一步 用“git add”把文件纳入Git管理,实际是把本地文件修改添加到暂存区

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

因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以commit就是往master分支上提交更改。

可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。一旦提交完后,如果你又没有对工作区做任何修改,那么工作区就是“干净”的。即:nothing to commit (working directory clean)

 

3.3 查看本地库状态

1)基本语法

git status

2)案例实操

3.3.1 首次查看(工作区没有任何文件)

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git status

On branch master

No commits yet

nothing to commit (create/copy files and use "git add" to track)

3.3.2 新增文件(hello.txt)

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ vim hello.txt

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

3.3.3 再次查看(检测到未追踪的文件)

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git status

On branch masterNo commits yetUntracked files:

  (use "git add <file>..." to include in what will be committed)

        hello.txt

nothing added to commit but untracked files present (use "git add" to track)

3.4 添加暂存区

3.4.1 将工作区的文件添加到暂存区

1)基本语法

git add 文件名

2)案例实操

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git add hello.txt

warning: LF will be replaced by CRLF in hello.txt.

The file will have its original line endings in your working directory.

git add . 添加项目中所有文件

3.4.2 查看状态(检测到暂存区有新文件)

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git status

On branch masterNo commits yetChanges to be committed:

  (use "git rm --cached <file>..." to unstage)

 

        new file:   hello.txt

Git工作目录下的文件状态信息:

Untracked 未跟踪(未被纳入版本控制)

Tracked 已跟踪(被纳入版本控制)

Unmodified 未修改状态

Modified 已修改状态

Staged 已暂存状态

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

红色表示新建文件或者新修改的文件,都在工作区.

绿色表示文件在暂存区

可以使用git status s 使输出信息更加简洁。?? : 表示未跟踪状态

3.5 提交本地库

3.5.1 将暂存区的文件提交到本地库

1)基本语法

git commit -m "日志信息" 文件名

2)案例实操

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git commit -m "my first commit" hello.txt

warning: LF will be replaced by CRLF in hello.txt.

The file will have its original line endings in your working directory.

[master (root-commit) 86366fa] my first commit

 1 file changed, 16 insertions(+)

 create mode 100644 hello.txt

²  git  commit

执行命令时需要填写提交日志,进入编辑模式

²  git  commit  –m “注释内容”   

直接用-m参数指定日志内容,推荐

commit 会生成一条版本记录,add只是添加暂存区,不会生成版本记录,建议多次add后,一次性commit,避免每次addcommit产生版本信息爆炸。

²  git commit -am "注释内容"

代码编辑完成后即可进行 add commit 操作

提示:添加和提交合并命令

3.5.2 查看状态(没有文件需要提交)

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git status

On branch master

nothing to commit, working tree clean

3.6 修改文件(hello.txt)

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ vim hello.txt

hello git! hello qiqi! 2222222222222

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

3.6.1 查看状态(检测到工作区有文件被修改)

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git status

On branch master

Changes not staged for commit:

  (use "git add <file>..." to update what will be committed)

  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   hello.txt

no changes added to commit (use "git add" and/or "git commit -a")

3.6.2 将修改的文件再次添加暂存区

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git add hello.txt

warning: LF will be replaced by CRLF in hello.txt.

The file will have its original line endings in your working directory.

3.6.3 查看状态(工作区的修改添加到了暂存区)

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git status

On branch master

Changes to be committed:

  (use "git reset HEAD <file>..." to unstage)

        modified:   hello.txt

3.7 历史版本

3.7.1 查看历史版本

1)基本语法

git reflog [文件名] 查看版本信息(显示本地库所有操作的历史记录,比如commit、reset)

git log  查看版本详细信息(只显示本地库commit的历史记录)

²  git log   查看所有文件日志

²  git log a.txt 查看某个文件日志

²  git log --pretty=oneline 如果日志很多,可以在一行显示

2)案例实操

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git reflog

087a1a7 (HEAD -> master) HEAD@{0}: commit: my third commit

ca8ded6 HEAD@{1}: commit: my second commit

86366fa HEAD@{2}: commit (initial): my first commit

3.7.2 版本穿梭

1)基本语法

git reset --hard 版本号

2)案例实操

--首先查看当前的历史记录,可以看到当前是在087a1a7这个版本

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git reflog

087a1a7 (HEAD -> master) HEAD@{0}: commit: my third commit

ca8ded6 HEAD@{1}: commit: my second commit

86366fa HEAD@{2}: commit (initial): my first commit

 

--切换到86366fa版本,也就是我们第一次提交的版本

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git reset --hard 86366fa

HEAD is now at 86366fa my first commit

--切换完毕之后再查看历史记录,当前成功切换到了86366fa版本

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git reflog

86366fa (HEAD -> master) HEAD@{0}: reset: moving to 86366fa

087a1a7 HEAD@{1}: commit: my third commit

ca8ded6 HEAD@{2}: commit: my second commit

86366fa (HEAD -> master) HEAD@{3}: commit (initial): my first commit

--然后查看文件hello.txt,发现文件内容已经变化

$ cat hello.txt

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

 

Git切换版本,底层其实是移动的HEAD指针。

三种情况下的回退操作:

o 未add,未commit (修改无效,回退到最后一次提交的数据)

·        git checkout-- a.txt 撤销修改(还原原来的文件)  <=Git 2.22

·        git restore -- a.txt 撤销修改(还原原来的文件)  >=Git2.23

·        注意:-- 可以省略 但不可以--a.txt  空格不可少

o 已add,未commit  软回退 (只是将文件的状态进行了回退)

·        git add a.txt

·        git reset a.txt 软回退:

·        git reset 软回退:

o 已add,已commit 硬回退 (回退到指定版本,内容变化)

·        git reset --hard 版本号

·        git reset --hard HEAD^ 一次回退一个版本,一个^代表一个版本

·        git reset --hard HEAD~n   回退n次操作

3.8 删除文件

   手动拷贝图片java.jpg到工作空间目录,并查看目录列表:ls -l

   添加:git add java.jpg

   提交:git commit -m "新建图片" java.jpg

   删除图片:rm java.jpg

   添加:git add java.jpg

   提交:git commit -m "删除图片"

   回退:git reset --hard HEAD^

   文件不是被删除了吗?怎么又回来啦!呵呵…

   处处留痕:git reflog

注意:rm java.jpg 的作用是删除工作区的文件,暂存区不知道;

git add java.jpg,将工作区对java.jpg的删除告诉暂存区。

git commit -m "删除图片" 将删除java.jpg告诉本地库

其中前两步可以简化为 git rm java.jpg ( 从工作区和暂存区删除文件Remove files from the working tree and from the index) 

或者后两步可以简化为 git commit -am "删除图片"

第4章 Git分支命令

4.1 什么是分支

在版本控制过程中,同时推进多个任务,为每个任务,我们就可以创建每个任务的单独分支。使用分支意味着程序员可以把自己的工作从开发主线上分离开来,开发自己分支的时候,不会影响主线分支的运行。对于初学者而言,分支可以简单理解为副本,一个分支就是一个单独的副本。(分支底层其实也是指针的引用)

4.2 分支的好处

同时并行推进多个功能开发,提高开发效率。

各个分支在开发过程中,如果某一个分支开发失败,不会对其他分支有任何影响。失败的分支删除重新开始即可。

4.3 分支的操作

命令名称

作用

git branch 分支名

创建分支

git branch -v

查看分支

git switch分支名

(git checkout分支名 <=git2.22 )

切换分支

git merge 分支名

把指定的分支合并到当前分支

git branch -d 分支名

删除分支(内容已经完成合并)

git branch -D  分支名

强制删除分支(有没有合并的内容)

git checkout 这个命令承担了太多职责,既被用来切换分支,又被用来恢复工作区文件,对用户造成了很大的认知负担。

Git社区发布了Git的新版本2.23。在该版本中,有一个特性非常引人瞩目,就是新版本的Git引入了两个新命令 git switch git restore,用以替代现在的 git checkout。换言之,git checkout 将逐渐退出历史舞台。

git checkout 的核心功能包括两个方面,一个是分支的管理,一个是文件的恢复。这两个核心功能,未来将由 git switch git restore 分别负责。

4.3.1 查看分支

1)基本语法

git branch -v

2)案例实操

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git branch -v

master 087a1a7 my third commit  代表当前所在的分区)

4.3.2 创建分支

1)基本语法

git branch 分支名

2)案例实操

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$  git branch hot-fix

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git branch -v

  hot-fix 087a1a7 my third commit  (刚创建的新的分支,并将主分支master的内容复制了一份)

* master  087a1a7 my third commit

4.3.3 修改分支

--在maste分支上做修改

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ vim hello.txt

--添加暂存区

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git add hello.txt

--提交本地库

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git commit -m "my forth commit" hello.txt

[master f363b4c] my forth commit

 1 file changed, 1 insertion(+), 1 deletion(-)

--查看分支

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git branch -v

  hot-fix 087a1a7 my third commit  (hot-fix分支并未做任何改变)

* master  f363b4c my forth commit (当前master分支已更新为最新一次提交的版本)

 

--查看master分支上的文件内容

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ cat hello.txt

hello git! hello qiqi! 2222222222222

hello git! hello qiqi! 3333333333333

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi! master test

hello git! hello qiqi!

 

4.3.4 切换分支

1)基本语法

git switch分支名

切换分支的本质就是移动HEAD指针,切换分支是观察.git/HEAD文件的变化

2)案例实操

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git checkout hot-fix

Switched to branch 'hot-fix'

--发现当先分支已由master改为hot-fix

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (hot-fix)

$

--查看hot-fix分支上的文件内容发现与master分支上的内容不同

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (hot-fix)

$ cat hello.txt

hello git! hello qiqi! 2222222222222

hello git! hello qiqi! 3333333333333

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

--在hot-fix分支上做修改

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (hot-fix)

$ cat hello.txt

hello git! hello qiqi! 2222222222222

hello git! hello qiqi! 3333333333333

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi! hot-fix test

--添加暂存区

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (hot-fix)

$ git add hello.txt

--提交本地库

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (hot-fix)

$ git commit -m "hot-fix commit" hello.txt

 

4.3.5 合并分支

1)基本语法

git merge 分支名

2)案例实操 在master分支上合并hot-fix分支

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git merge hot-fix

Auto-merging hello.txt

CONFLICT (content): Merge conflict in hello.txt

Automatic merge failed; fix conflicts and then commit the result.

4.3.6 产生冲突

冲突产生的表现:后面状态为MERGING

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master|MERGING)

$ cat hello.txt

hello git! hello qiqi! 2222222222222

hello git! hello qiqi! 3333333333333

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

<<<<<<< HEAD

hello git! hello qiqi! master test

hello git! hello qiqi!

=======

hello git! hello qiqi!

hello git! hello qiqi! hot-fix test

>>>>>>> hot-fix

 

冲突产生的原因:

合并分支时,两个分支在同一个文件的同一个位置有两套完全不同的修改。Git无法替我们决定使用哪一个。必须人为决定新代码内容。

查看状态(检测到有文件有两处修改)

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master|MERGING)

$ git status

On branch master

You have unmerged paths.

  (fix conflicts and run "git commit")

  (use "git merge --abort" to abort the merge)

 

Unmerged paths:

  (use "git add <file>..." to mark resolution)

 

        both modified:   hello.txt

 

no changes added to commit (use "git add" and/or "git commit -a")

4.3.7 解决冲突

1)编辑有冲突的文件,删除特殊符号,决定要使用的内容

特殊符号:<<<<<<< HEAD 当前分支的代码 =======  合并过来的代码  >>>>>>> hot-fix

hello git! hello qiqi! 2222222222222

hello git! hello qiqi! 3333333333333

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi! master test

hello git! hello qiqi! hot-fix test

2)添加到暂存区

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master|MERGING)

$ git add hello.txt

3)执行提交(注意:此时使用git commit命令时不能带文件名

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master|MERGING)

$ git commit -m "merge hot-fix"

[master 69ff88d] merge hot-fix

--发现后面MERGING消失,变为正常

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$

4.4 避免冲突

l  容易冲突的操作方式

u  多个人同时操作了同一个文件

u  一个人一直写不提交

u  修改之前不更新最新代码

u  提交之前不更新最新代码

u  擅自修改同事代码

l  减少冲突的操作方式

u  养成良好的操作习惯,pull在修改,修改完立commitpush

u  一定要确保自己正在修改的文件是最新版本的

u  各自开发各自的模块

u  如果要修改公共文件,一定要先确认有没有人正在修改

u  下班前一定要提交代码,上班第一件事拉取最新代码

u  一定不要擅自修改同事的代码

5 认识Git远程库

5.1 Git代码托管服务

前面我们已经知道了Git中存在两种类型的仓库,即本地仓库远程仓库。那么我们如何搭建Git远程仓库呢?我们可以借助互联网上提供的一些代码托管服务来实现,其中比较常用的有GitHub码云GitLab等。

l  gitHub 地址:https://github.com/

是一个面向开源及私有软件项目的托管平台,因为只支持Git 作为唯一的版本库格式进行托管,故名gitHub

l  码云(地址: https://gitee.com/

国内的一个代码托管平台,由于服务器在国内,所以相比GitHub,码云速度会更快

l  GitLab (地址: https://about.gitlab.com/

是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务

5.2 Github简介

1.是什么: github是一个git项目托管网站,主要提供基于git的版本托管服务。官网地址: https://github.com/

2.能干嘛: github是一个基于git的代码托管平台 Git 并不像 SVN 那样有个中心服务器。目前我们使用到的 Git 命令都是在本地执行,如果你想通过 Git 分享你的代码或者与其他开发人员合作。 你就需要将数据放到一台其他开发人员能够连接的服务器上。

5.3 Git远程工作机制

仓库:

本地仓库:是在开发人员自己电脑上的Git仓库

远程仓库:是在远程服务器上的Git仓库

团队内协作

跨团队协作

操作:

add:添加,就是将工作区代码添加到暂存区

commit:提交,就是将本地暂存区代码上传到本地仓库中

push:推送,就是将本地仓库代码上传到远程仓库

clone:克隆,就是将远程仓库复制到本地

pull:拉取,就是将远程仓库代码下载到本地仓库

5.4 Github/Gitee实战步骤和命令

·        一共9个步骤:我们完全按照9个步骤的流程来进行练习。做到熟练掌握。

·        涉及到远程库命令如下

命令名称

作用

git remote -v

查看当前所有远程地址别名

git remote add 别名 远程地址

起别名

git clone 远程地址

将远程仓库的内容克隆到本地

git push 别名 分支

推送本地分支上的内容到远程仓库

git pull 远程库地址别名 远程分支名

将远程仓库对于分支最新内容拉下来后与当前本地分支直接合并

6 GitHub操作

账号

姓名

验证邮箱

qiqiyueyue

岳不群

qiqiyueyue@aliyun.com

qiqilinghuchong

令狐冲

qiqilinghuchong@163.com

qiqidongfang1

东方不败

qiqidongfang@163.com

:此三个账号为讲师使用账号,同学请自行注册,然后三个同学为一组进行团队协作!

6.1 团队内操作

6.1.1 创建远程仓库别名

1)基本语法

git remote -v 查看当前所有远程地址别名

git remote add 别名 远程地址

2)案例实操

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git remote -v

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git remote add ori https://github.com/qiqiyueyue/git-shTest.git

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git remote -v

ori     https://github.com/qiqiyueyue/git-shTest.git (fetch)

ori     https://github.com/qiqiyueyue/git-shTest.git (push)

https://github.com/qiqiyueyue/git-shTest.git

这个地址在创建完远程仓库后生成的连接,如图所示红框中

6.1.2 推送本地分支到远程仓库

1)基本语法

git push 别名 分支

2)案例实操

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git push ori master

Logon failed, use ctrl+c to cancel basic credential prompt.

Username for 'https://github.com': qiqiyueyue

Counting objects: 3, done.

Delta compression using up to 12 threads.

Compressing objects: 100% (2/2), done.

Writing objects: 100% (3/3), 276 bytes | 276.00 KiB/s, done.

Total 3 (delta 0), reused 0 (delta 0)

To https://github.com/qiqiyueyue/git-shTest.git

 * [new branch]      master -> master

此时发现已将我们master分支上的内容推送到GitHub创建的远程仓库。

6.1.3 克隆远程仓库到本地

1)基本语法

git clone 远程地址

2)案例实操

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/pro-linghuchong

$ git clone https://github.com/qiqiyueyue/git-shTest.git

Cloning into 'git-shTest'...

remote: Enumerating objects: 3, done.

remote: Counting objects: 100% (3/3), done.

remote: Compressing objects: 100% (2/2), done.

remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0

Unpacking objects: 100% (3/3), done.

https://github.com/qiqiyueyue/git-shTest.git

这个地址为远程仓库地址,克隆结果:初始化本地仓库

--创建远程仓库别名

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/pro-linghuchong/git-shTest (master)

$ git remote -v

origin  https://github.com/qiqiyueyue/git-shTest.git (fetch)

origin  https://github.com/qiqiyueyue/git-shTest.git (push)

小结:clone会做如下操作。1、拉取代码。2、初始化本地仓库。3、创建别名

6.1.4 邀请加入团队

1)选择邀请合作者

2)填入想要合作的人

3)复制地址并通过微信钉钉等方式发送给该用户,复制内容如下:https://github.com/qiqiyueyue/git-shTest/invitations

4)在qiqilinghuchong这个账号中的地址栏复制收到邀请的链接,点击接受邀请。

5)成功之后可以在qiqilinghuchong这个账号上看到git-Test的远程仓库。

6)令狐冲可以修改内容并push到远程仓库。

--编辑clone下来的文件

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/pro-linghuchong/git-shTest (master)

$ vim hello.txt

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/pro-linghuchong/git-shTest (master)

$ cat hello.txt

hello git! hello qiqi! 2222222222222

hello git! hello qiqi! 33333333333333

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi! 我是最帅的,比岳不群还帅

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi! master test

hello git! hello qiqi! hot-fix test

--将编辑好的文件添加到暂存区

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/pro-linghuchong/git-shTest (master)

$ git add hello.txt

--将暂存区的文件上传到本地库

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/pro-linghuchong/git-shTest (master)

$ git commit -m "lhc commit" hello.txt

[master 5dabe6b] lhc commit

 1 file changed, 1 insertion(+), 1 deletion(-)

--将本地库的内容push到远程仓库

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/pro-linghuchong/git-shTest (master)

$ git push origin master

Logon failed, use ctrl+c to cancel basic credential prompt.

Username for 'https://github.com': qiqilinghuchong

Counting objects: 3, done.

Delta compression using up to 12 threads.

Compressing objects: 100% (2/2), done.

Writing objects: 100% (3/3), 309 bytes | 309.00 KiB/s, done.

Total 3 (delta 1), reused 0 (delta 0)

remote: Resolving deltas: 100% (1/1), completed with 1 local object.

To https://github.com/qiqiyueyue/git-shTest.git

   7cb4d02..5dabe6b  master -> master

7)回到qiqiyueyue的GitHub远程仓库中可以看到,最后一次是lhc提交的。

6.1.5 拉取远程库内容

1)基本语法

git pull 远程库地址别名 远程分支名

2)案例实操

--将远程仓库对于分支最新内容拉下来后与当前本地分支直接合并

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ git pull ori master

remote: Enumerating objects: 5, done.

remote: Counting objects: 100% (5/5), done.

remote: Compressing objects: 100% (1/1), done.

remote: Total 3 (delta 1), reused 3 (delta 1), pack-reused 0

Unpacking objects: 100% (3/3), done.

From https://github.com/qiqiyueyue/git-shTest

 * branch            master     -> FETCH_HEAD

   7cb4d02..5dabe6b  master     -> ori/master

Updating 7cb4d02..5dabe6b

Fast-forward

 hello.txt | 2 +-

 1 file changed, 1 insertion(+), 1 deletion(-)

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ cat hello.txt

hello git! hello qiqi! 2222222222222

hello git! hello qiqi! 33333333333333

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi! 我是最帅的,比岳不群还帅

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi!

hello git! hello qiqi! master test

hello git! hello qiqi! hot-fix test

6.2 Github实战—团队内协作(协作冲突演示)

6.2.1.协作冲突

在上传或同步代码时,由于你和他人都改了同一文件的同一位置的代码,版本管理软件无法判断究竟以谁为准,就会报告冲突,需要程序员手工解决。

6.3 跨团队协作

6.3.1 Fork

概念:

现在的情景是,用叉子把别人的东西(copy no cut)叉到你的碗里~

就是把别人的项目clone一份,但是owner变成自己,这样你就可以在遵守Open source license的前提下任意修改这个项目了。

相当于你在原项目的主分支上又建立了一个分支,你可以在该分支上任意修改,如果想将你的修改合并到原项目中时,可以pull request

这样原项目的作者就可以将你修改的东西合并到原项目的主分支上去,这样你就为开源项目贡献了代码,开源项目就会在大家共同的努力下不断壮大和完善。

流程:(zhangsan和lisi是一个团队的人,wangwu是另一个团队的人

第三方账号登录(wangwu),搜索某账号找到某项目(zhangsan),然后点击Fork按钮,这样就将该项目克隆一份到当前账号(wangwu)内,然后进行修改,提交pull request,告诉对方(zhangsan)已经修改了,请求合并;

当前用户登录(zhangsan)后,可以看到小铃铛中的消息提醒,查看到pull request,然后,选择合并或拒绝。

6.4 SSH免密登录

我们可看到远程仓库中还有一个SSH的地址,因此我们也可以使用SSH进行访问。

在管理Git项目上,很多时候都是直接使用https url克隆到本地,当然也有有些人使用SSH url克隆到本地。这两种方式的主要区别在于:

使用https url克隆对初学者来说会比较方便,复制https url然后到git Bash里面直接用clone命令克隆到本地就好了,但是每次fetch和push代码都需要输入账号和密码,这也是https方式的麻烦之处。

而使用SSH url克隆却需要在克隆之前先配置和添加好SSH key,因此,如果你想要使用SSH url克隆的话,你必须是这个项目的拥有者。否则你是无法添加SSH key的,另外ssh默认是每次fetch和push代码都不需要输入账号和密码,如果你想要每次都输入账号密码才能进行fetch和push也可以另外进行设置。

具体操作如下:

--进入当前用户的家目录

Layne@LAPTOP-Layne MINGW64 /d/Git-Space/SH0720 (master)

$ cd

--删除.ssh目录

Layne@LAPTOP-Layne MINGW64 ~

$ rm -rvf .ssh

removed '.ssh/known_hosts'

removed directory '.ssh'

--运行命令生成.ssh秘钥目录[注意:这里-C这个参数是大写的C]

Layne@LAPTOP-Layne MINGW64 ~

$ ssh-keygen -t rsa -C qiqiyueyue@aliyun.com

Generating public/private rsa key pair.

Enter file in which to save the key (/c/Users/Layne/.ssh/id_rsa):

Created directory '/c/Users/Layne/.ssh'.

Enter passphrase (empty for no passphrase):

Enter same passphrase again:

Your identification has been saved in /c/Users/Layne/.ssh/id_rsa.

Your public key has been saved in /c/Users/Layne/.ssh/id_rsa.pub.

The key fingerprint is:

SHA256:7CPfRLITKcYDhaqpEDeok7Atvwh2reRmpxxOC6dkY44 qiqiyueyue@aliyun.com

The key's randomart image is:

+---[RSA 2048]----+

|     ..          |

|    ..           |

| . ..            |

|+ +  o . .       |

|oO .  = S .      |

|X . .. + =       |

|+@ * .. = .      |

|X.&o+. o =       |

|Eo+Oo   . .      |

+----[SHA256]-----+

--进入.ssh目录查看文件列表

Layne@LAPTOP-Layne MINGW64 ~

$ cd .ssh

Layne@LAPTOP-Layne MINGW64 ~/.ssh

$ ll -a

total 21

drwxr-xr-x 1 Layne 197609    0 11月 25 19:27 ./

drwxr-xr-x 1 Layne 197609    0 11月 25 19:27 ../

-rw-r--r-- 1 Layne 197609 1679 11月 25 19:27 id_rsa

-rw-r--r-- 1 Layne 197609  406 11月 25 19:27 id_rsa.pub

--查看id_rsa.pub文件内容

Layne@LAPTOP-Layne MINGW64 ~/.ssh

$ cat id_rsa.pub

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDRXRsk9Ohtg1AXLltsuNRAGBsx3ypE1O1Rkdzpml1woa6y6G62lZri3XtCH0F7GQvnMvQtPISJFXXWo+jFHZmqYQa/6kOIMv2sszcoj2QtwllGXTPn/4T2h/cHjSHfc+ks8OYP7OWOOefpOCbYY/7DWYrl89k7nQlfd+A1FV/vQmcsa1LP5ihqjpjms2CoUUen8kZHbjwHBAHQHWRE+Vc371MG/dwINvCi8n7ibI86o2k0dW0+8SL+svPV/Y0G9m+RAqgec8b9U6DcSSAMH5uq4UWfnAcUNagb/aJQLytrH0pLa8nMv3XdSGNNoAGBFeW2+K81XrmkP27FrLI6lDef qiqiyueyue@aliyun.com

复制id_rsa.pub文件内容,登录GitHub,点击用户头像→Settings→SSH and GPG keys

接下来再往远程仓库push东西的时候使用SSH连接就不需要登录了。

7 IDEA集成Git

7.1 配置Git忽略文件

1)Eclipse特定文件

2)IDEA特定文件

3)Maven工程的target目录

问题1:为什么要忽略他们?

答:与项目的实际功能无关,不参与服务器上部署运行。把它们忽略掉能够屏蔽IDE工具之间的差异。

问题2:怎么忽略?

1)创建忽略规则文件xxxx.ignore(前缀名随便起,建议是git.ignore)

这个文件的存放位置原则上在哪里都可以,为了便于让~/.gitconfig文件引用,建议也放在用户家目录下

git.ignore文件模版内容如下:

# Compiled class file

*.class

# Log file

*.log

# BlueJ files

*.ctxt

# Mobile Tools for Java (J2ME)

.mtj.tmp/

# Package Files #

*.jar

*.war

*.nar

*.ear

*.zip

*.tar.gz

*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml

hs_err_pid*

.classpath

.project

.settings

target

.idea

*.iml

2)在.gitconfig文件中引用忽略配置文件(此文件在Windows的家目录中)

[user]

    name = Layne

    email = Layne@qiqi.com

[core]

    excludesfile = C:/Users/asus/git.ignore

注意:这里要使用“正斜线(/)”,不要使用“反斜线(\)”

7.2 定位Git程序

7.3 初始化本地库

创建Maven项目,比如gitdemo。但是此处和git没有关系,没有进行版本控制。

选择要创建Git本地仓库的工程。

7.4 添加到暂存区

右键点击项目选择Git -> Add将项目添加到暂存区。

7.5 提交到本地库

7.6 切换版本

在IDEA的左下角,点击Version Control,然后点击Log查看版本

右键选择要切换的版本,然后在菜单里点击Checkout Revision。

7.7 创建分支

选择Git,在Repository里面,点击Branches按钮。

在弹出的Git Branches框里,点击New Branch按钮。

填写分支名称,创建hot-fix分支。

然后在IDEA的右下角看到hot-fix,说明分支创建成功,且当前已切换成hot-fix分支

7.8 切换分支

在IDEA窗口的右下角,切换到master分支。

然后在IDEA窗口的右下角看到了master,说明master分支切换成功。

7.9 合并分支

在IDEA窗口的右下角,将hot-fix分支合并到当前master分支。

如果代码没有冲突,分支直接合并成功,分支合并成功以后,代码自动提交,无需手动提交本地库。

7.10 解决冲突

如图所示,如果master分支和hot-fix分支都修改了代码,在合并分支的时候就会发生冲突。

我们现在站在master分支上合并hot-fix分支,就会发生代码冲突。

       点击Conflicts框里的Merge按钮,进行手动合并代码。

       手动合并完代码以后,点击右下角的Apply按钮。

代码冲突解决,自动提交本地库。

8 IDEA集成GitHub

8.1 设置GitHub账号

如果出现401等情况连接不上的,是因为网络原因,可以使用以下方式连接:

然后去GitHub账户上设置token

点击生成token

复制红框中的字符串到idea中。

点击登录。

8.2 分享工程到GitHub

来到GitHub中发现已经帮我们创建好了gitTest的远程仓库。

8.3 push推送本地库到远程库

右键点击项目,可以将当前分支的内容pushGitHub的远程仓库中。

注意:push是将本地库代码推送到远程库,如果本地库代码跟远程库代码版本不一致,push的操作是会被拒绝的。也就是说,要想push成功,一定要保证本地库的版本要比远程库的版本高!因此一个成熟的程序员在动手改本地代码之前,一定会先检查下远程库跟本地代码的区别!如果本地的代码版本已经落后,切记要先pull拉取一下远程库的代码,将本地代码更新到最新以后,然后再修改,提交,推送!

8.4 pull拉取远程库到本地库

右键点击项目,可以将远程仓库的内容pull到本地仓库。

注意:pull是拉取远端仓库代码到本地,如果远程库代码和本地库代码不一致,会自动合并,如果自动合并失败,还会涉及到手动解决冲突的问题。

8.5 clone克隆远程库到本地

clone下来的项目创建一个工程,然后点击Next

第9章 国内代码托管中心-码云

9.1 IDEA集成码云

9.1.1 IDEA安装码云插件

Idea默认不带码云插件,我们第一步要安装Gitee插件。

如图所示,在Idea插件商店搜索Gitee,然后点击右侧的Install按钮。

Idea链接码云和链接GitHub几乎一样,安装成功后,重启Idea。

       Idea重启以后在Version Control设置里面看到Gitee,说明码云插件安装成功。

      然后在码云插件里面添加码云帐号,我们就可以用Idea连接码云了。

9.1.2 IDEA连接码云

Idea连接码云和连接GitHub几乎一样,首先在Idea里面创建一个工程,初始化git工程,然后将代码添加到暂存区,提交到本地库,这些步骤上面已经讲过,此处不再赘述。

Ø  将本地代码push到码云远程库

自定义远程库链接。

给远程库链接定义个name,然后再URL里面填入码云远程库的HTTPS链接即可。码云服务器在国内,用HTTPS链接即可,没必要用SSH免密链接。

然后选择定义好的远程链接,点击Push即可。

看到提示就说明Push远程库成功。

去码云远程库查看代码。

只要码云远程库链接定义好以后,对码云远程库进行pull和clone的操作和Github一致,此处不再赘述。

9.2 码云复制GitHub项目

码云提供了直接复制GitHub项目的功能,方便我们做项目的迁移和下载。

具体操作如下:

       将GitHub的远程库HTTPS链接复制过来,点击创建按钮即可。

如果GitHub项目更新了以后,在码云项目端可以手动重新同步,进行更新!

动物装饰