一、git介绍
1、git简介
Git 是一个开源的分布式版本控制系统(最先进的,没有之一),用于敏捷高效地处理任何或小或大的项目。
Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。
Git 与常用的版本控制工具 CVS, Subversion(SVN) 等不同,它采用了分布式版本库的方式,不必服务器端软件支持。
2、集中式(SVN)VS分布式(git)
集中式版本控制系统:版本库是集中存放在中央服务器的,工作时要先从中央服务器取得最新的版本,完成工作后,再把自己的文件推送给中央服务器。集中式版本控制系统在工作时需要联网。
分布式版本控制系统:没有“中央服务器”,每个人的电脑上都是一个完整的版本库,不需要联网。和集中式版本控制系统相比,分布式版本控制系统的安全性要高很多,每个人电脑里都有完整的版本库,某一个人的电脑坏掉了,从其他人那里复制一个就可以了。而集中式版本控制系统的中央服务器要是出了问题,所有人都没法干活了。
实际使用分布式版本控制系统的时候,很少在两人之间的电脑上推送版本库的修改,因为可能俩人不在同一局域网内,两台电脑互相访问不了,也可能另一台电脑没有开机。所以分布式版本控制系统通常也有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已。
Git的优势不单是不必联网这么简单,后面我们还会看到Git极其强大的分支管理。
二、git下载安装与名词解释
1、下载
Linux安装:
apt-get git install git
我下好的windows:https://pan.baidu.com/s/1RCB01vaF8ayo7KXYjn5pfA?pwd=1473
2、安装
! !!可以一直点下一步
2.1、使用许可声明
2.2、选择安装目录
2.3、选择安装组件
2.4、选择开始菜单文件
2.5、选择Git默认编辑器
2.6、决定初始化新项目(仓库)的主干名字
2.7、调整Git的环境变量
2.8、选择 SSH 执行文件
2.9、选择HTTPS后端传输
2.10、配置行尾符号转换
2.11、配置终端模拟器以与 Git Bash 一起使用
2.12、“git pull” 默认行为
2.13、选择一个凭证帮助程序
2.14、配置额外的选项
2.15、配置实验性选项
2.16、安装中
2.17、安装完成
“Launch Git Bash”:启动 Git Bash 终端。
“View Release Notes”:查看版本说明。
3、功能简介
3.1、Git Bash(同2.17 Launch Git Bash)
Git Bash 是一个命令行工具,提供了类似于 Linux Shell 的环境,使用户能够在 Windows 系统上使用类Unix命令。
通过 Git Bash,用户可以使用 Git 的命令行功能,执行版本控制任务,例如克隆仓库、提交更改等。
3.2、Git CMD
Git CMD 是一个在 Windows 命令提示符中运行的命令行工具。与 Git Bash 不同,Git CMD 更接近于 Windows 命令行环境。
类似于 Git Bash,Git CMD 也允许用户在命令行中执行 Git 命令,进行版本控制操作。
3.3、Git FAQs(Frequently Asked Questions)
Git FAQs(Frequently Asked Questions)包含常见问题和解答,是一份常见问题的集合,为用户提供了解决常见问题的参考资料。
用户可以在 Git FAQs 中查找关于 Git 的常见问题的答案,以解决遇到的问题。
3.4、Git GUI
Git GUI 是 Git 的图形用户界面工具,提供了一个可视化的界面,使用户能够执行版本控制操作而无需使用命令行。
通过 Git GUI,用户可以更直观地查看仓库状态、提交更改、查看历史记录等,适用于那些不太习惯使用命令行的用户。
3.5、Git Release Note(同2.17View Release Notes)
Git Release Note 包含了每个 Git 版本的发布说明,记录了每个版本的新功能、改进和修复的问题等信息。
用户可以通过查阅 Git Release Note 了解每个 Git 版本的更新内容,以了解新功能、改进和潜在的问题。
4、基本的名词和概念
- 仓库(Repository):
一个 Git 仓库是项目的存储空间,包含项目文件和版本历史记录。可以是本地仓库(Local Repository)或远程仓库(Remote Repository)。 - 工作区(Working Directory):
工作区是你在电脑上能看到的项目目录,包含项目文件和子文件夹。 - 暂存区(Staging Area):
暂存区是一个中间区域,用于存放将要提交的修改。在提交前,你需要将修改先添加到暂存区。 - 提交(Commit):
提交是对工作区和暂存区的修改进行保存的操作。每次提交都有一个唯一的标识符(哈希值),并包含了修改的描述信息。 - 分支(Branch):
分支是项目的一个工作线,可以创建新的分支用于开发新功能或修复 bug,然后将其合并回主分支。 - 主分支(Main/Branch):
主分支是项目的默认分支,通常被称为 master 或 main,是项目的主要开发线。 - 远程仓库(Remote Repository):
远程仓库是托管在网络上的项目副本,可以在 GitHub、GitLab、Bitbucket 等平台上进行多人协作。 - 克隆(Clone):
克隆是从远程仓库复制整个项目到本地,创建一个本地仓库的副本。 - 拉取(Pull):
拉取是从远程仓库获取最新修改,将远程仓库的变化更新到本地。 - 推送(Push):
推送是将本地的修改上传到远程仓库,使得远程仓库也包含最新的工作。 - 合并(Merge):
合并是将不同分支的修改合并到一起,通常用于将新功能或修复的代码合并回主分支。 - 冲突(Conflict):
冲突发生在合并分支时,表示有两处或多处修改互相冲突,需要手动解决。
三、git基本使用
1、配置用户信息:
安装完,后第一件事就是设置自己的用户名和邮箱地址,这样才可以知道哪些人提交了什么代码。
进入【git Bash】,设置全局用户名和邮箱:
# 设置全局用户名和邮箱地址(只设置当前项目的,去掉“--global”)
git config [--global] user.name "用户名"
git config [--global] user.email "邮箱地址"
eg:
git config [--global] user.name "zqx"
git config [--global] user.email "[email protected]"
# 查看全局用户名和邮箱地址
git config [--global] user.name
git config [--global] user.email
通过 以上命令配置的用户名和邮箱地址,会被写入到 C:/Users/用户名文件夹/.gitconfig 文件中。这个文件是 Git 的全局配置文件,配置一次即可永久生效。
如果只想本次项目中使用这个用户名和邮箱地址,把【--global】去掉即可
# 设置本项目用户名和邮箱地址
git config user.name "用户名"
git config user.email "邮箱地址"
# 查看本项目用户名和邮箱地址
git config user.name
git config user.email
保存在当前项目的 .git/config 文件里。
2、提交到本地仓库基本流程
1.创建仓库:
新建仓库:git init
git init [项目路径]
克隆仓库:git clone
git clone <远程仓库地址> [本地目录]
# eg:
git clone https://github.com/zqx1473/gitTest.git
2.---编码
3.添加新文件到暂存区:git add
git add [filename]
4.提交版本到本地仓库:git commit
git commit [-m "代码提交信息"]
2.1、新建仓库
----新建项目文件夹(原有项目可跳过)
进入项目文件夹
右键,选择【Open Git Bash here】,
初始化仓库:git init
# 当前目录作为仓库
git init
# or
git init .
# or
git init ./
# 指定目录作为仓库
git init [projectpath]
命令行执行命令后【.git】文件夹出现
生成的【.git】目录如下
2.2、编码
好了该你自由发挥了,这里就简单用txt举个例。
2.3、添加新文件到暂存区:git add
# 添加单独文件
git add <filename>
# 添加多个文件
git add <filename1> [filename2]
# or
git add <filename1>
git add <filename2>
# 添加当前目录全部文件(不包括忽略文件)----建议使用
# or
git add . 等价于下面的命令
# or
git add ./
# 添加当前目录全部文件(忽略文件给出提示,【.】开头的文件不添加)
git add *
这个命令只是将文件信息添加到暂存区,
执行完这一步后仓库是没有变化的
2.4、提交版本到本地仓库:git commit -m "代码提交信息"
git commit [-m "代码提交信息"]
# 不使用【-m】,会出现编辑器来让你写自己的注释信息
git commit
# 当我们修改了很多文件,而不想每一个都add,想commit自动来提交本地修改,我们可以使用【-a】标识。
git commit [-a] [-m "代码提交信息"]
# !!!千万注意,-a不会造成新文件被提交,只能修改。
执行这行命令后,才会正式提交到本地仓库
可以看到【.git】明显变化
同时提交文件,图标左下角多了个【√】
一般【git add】多次使用,最后【git commit -m " "】进行一次提交
使用【git commit】提交,进入编辑器效果如下:(编辑器用法,可了解vi编辑器)
3、查看相关信息
3.1、查看文件状态
git中暂存区文件有四种状态
没有被托管的文件
1、未跟踪(untracked) test.txt -- 新创建的文件
已被托管(曾经add、commit过)
2、已暂存(changes to be committed) new file: test.txt -- add后
3、已提交(nothing to commit) <nothing> -- commit后
4、已修改(modified) modified: test.txt -- commit后又进行了文件修改
3.5、修改后已暂存(和3为同样状态) modified: test.txt --修改后又commot
4.5、已删除(deleted) deleted: test.txt --已删除
# 查看状态
git status
# 查看简略状态
git status -s
这里在新建一个文件
3.2、查看日志信息
我们修改文件重新提交
# 查看详细日志信息
git log
# 查看简略日志信息
git log --oneline
# 版本号显示完全的简略日志信息(每个提交的信息只显示一行)
git log --pretty=oneline
# 系统设置
git config format.pretty oneline
# 查看你所有的提交的记录
git reflog
最上面显示的最新的版本
3.3、比较不同状态下的文件差异
git diff [options] [source1] [source2] [filename]
# 尚未缓存的改动
git diff
# 查看已缓存的改动
git diff --cached
# 查看已缓存的与未缓存的所有改动
git diff HEAD
# 显示摘要而非整个 diff
git diff --stat
如:查看版本库里最新版本与工作区的区别
git diff HEAD -- test.txt
# -- 表示当前工作目录,后面接的是路径,以避免歧义
4、版本控制
# 修改完之后查看工作区和版本库里面最新版本的区别
git diff HEAD -- test.txt
4.1、从工作区恢复
改动了代码,想放弃修改(没有add)
git checkout -- test.txt
4.2、从暂存区恢复
改动了代码,也add了,想放弃(没有commit)
git reset HEAD test.txt
git checkout -- test.txt
【git reset HEAD test.txt】只是回到了【add】之前,代码文件不会发生改变,也就是回到了上一个情况(5.2)
然后在进行【git checkout -- test.txt】
4.3、版本回滚(版本回退):已经提交到版本库,想撤回本次提交
git reset --hard 版本号
使用命令之后就会发现,代码水灵灵的变回了原来的模样
5、分支与合并
5.1、创建和切换分支
# 创建分支
git branch <分支名>
# 切换分支
git checkout <分支名>
# 创建并切换分支
git checkout -b <分支名>
5.2、查看分支
# 查看所有分支
git branch
# 查看远程分支
git branch -r
# 查看所有本地和远程分支
git branch -a
5.3、合并分支
git merge <被合并的分支名>
5.4、删除分支
git branch -d <分支名>
5.6、查看分支差异
# 查看版本库里面最新版本和工作区的区别
git diff <source_branch> <target_branch>
# 比较两个分支之间特定目录的差异
git diff HEAD -- test.txt
6、对远程仓库的使用
克隆仓库:git clone
git clone <远程仓库地址>
# eg:
git clone https://github.com/zqx1473/gitTest.git
推送
git push [-u] origin main
# -u,记录远端分支默认值,下次还要向这个分支push时,可以将命令简化为【git push】
拉取
git pull origin <分支名>
6.1、创建远程仓库
常见远程仓库:
github:GitHub: Let’s build from here · GitHub
码云(gitee):Gitee - 基于 Git 的代码托管和研发协作平台
gitlab:The most-comprehensive AI-powered DevSecOps platform | GitLab
Bitbucket:Bitbucket | Git solution for teams using Jira
codeup(阿里云):阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台
coding(腾讯云):代码托管 | 极速 Git 代码仓库服务-CODING-腾讯云
gitcode:GitCode - 全球开发者的开源社区,开源代码托管平台
以github为例
可以填完仓库名字,直接点创建
看github已经贴心的把建库和推送方法都告诉我们了
# 从命令行上创建一个新的仓库
echo "# git_project" >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/zqx1473/git_project.git
git push -u origin main
# 从命令行推送一个现有的仓库
git remote add origin https://github.com/zqx1473/git_project.git
git branch -M main
git push -u origin main
6.2、克隆(检出仓库):git clone
克隆是将整个远程仓库克隆到本地(将整个远程仓库文件夹copy到你的本地,一般只会在项目开始
的时候执行一次
)
git clone <仓库地址> [你想创建的本地项目名]
# eg:远程
git clone https://github.com/zqx1473/git_project.git
# eg 也可以克隆本地的
git clone git_project
6.3、推送:git push
设定远程仓库地址
# 关联远程仓库
git remote add origin <远程仓库地址>
# eg
git remote add origin https://github.com/zqx1473/git_project.git
# 查看远程仓库地址
git remote -v
# or
git config --get remote.origin.url
将【master】】分重命名为【main】
(为了避免使用具有带有潜在不适宜历史意义的术语,”master”一词在过去用于指代奴隶制度中的主人,因此有一些人认为这个术语带有种族主义和剥削的历史背景。)
git branch -M main
推送到远程仓库
git push [-u] origin main
# -u,记录远端分支默认值,下次还要向这个分支push时,可以将命令简化为【git push】
git push
6.4、拉取:git pull
用于多人开发。比如别人写的代码文件提交到远程仓库,通过这个命令就可以将远程仓库代码拉取到本地.
这个命令不会拉取所有代码,只是拉取远程上面新增的代码(把别人写的代码合并到你的本地).
git pull [远程仓库命名:默认“origin”] [分支名]
# 远程主机 origin 的 master 分支拉取过来,与本地的 brantest 分支合并。
git pull origin master:brantest
# 如果远程分支是与当前分支合并,则冒号后面的部分可以省略。
git pull origin master
我们在远程仓库中创建一个【README】文件,模拟其他人对项目进行修改,
然后进行pull
可能会报错
fatal: unable to access 'https://github.com/zqx1473/git_project.git/': Failed to connect to github.com port 443 after 21128 ms: Couldn't connect to server
解决:
step1:cmd输入以下命令:清除缓存后再重新进行 git 操作即可
ipconfig/flushdns
step2:取消代理
// 取消http的代理
git config --global --unset http.proxy
// 取消https的代理
git config --global --unset https.proxy
然后执行【git pull】即可
发现【README】出现
四、git详细理解
1、基本理解
1.1、 git的三个区
-
工作区: 处理工作的区域 ----------------------------------- 你的项目文件夹(项目目录)
-
暂存区(stage/index,索引): 临时存放的区域 ---- 在.git文件夹内的index中 (二进制记录)
-
版本库(本地git仓库): 最终的存放区域 ------------- 指的整个.git文件夹 (也认为是版本库)
HEAD表示当前分支,
-
当对工作区修改的文件执行 【git add】 命令时,暂存区的目录树被更新,同时工作区修改的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。
【这里用一个新项目演示】
-
当执行提交操作【git commit】时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。
-
当执行 【git reset HEAD】 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。
-
当执行 【git rm --cached <file>】 命令时,会直接从暂存区删除文件,工作区则不做出改变。
-
当执行 【git checkout .】 或者 【git checkout -- <file>】 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区中的改动。
-
当执行 【git checkout HEAD .】 或者 【git checkout HEAD <file>】 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。
相当于【git reset HEAD 】 +【git checkout -- <file>】
1.2、基本用法图解
绿色的5位字符表示提交的ID,分别指向父节点。分支用橘色显示,分别指向特定的提交。当前分支由附在其上的HEAD标识。 这张图片里显示最后5次提交,ed489是最新提交。 main分支指向此次提交,另一个stable分支指向祖父提交节点。
1.2.1、diff
查看两次提交之间的变动
1.2.2、commit
提交时,git用暂存区域的文件创建一个新的提交,并把此时的节点设为父节点。然后把当前分支指向新的提交节点。下图中,当前分支是main。 在运行命令之前,main指向ed489,提交后,main指向新的节点f0cec并以ed489作为父节点。
即便当前分支是某次提交的祖父节点,git会同样操作。下图中,在main分支的祖父节点stable分支进行一次提交,生成了1800b。 这样,stable分支就不再是main分支的祖父节点。此时,合并是必须的。
如果想更改一次提交,使用 git commit --amend
。git会使用与当前提交相同的父节点进行一次新提交,旧的提交会被取消。
1.2.3、Checkout
checkout命令用于从历史提交(或者暂存区域)中拷贝文件到工作目录,也可用于切换分支。
git会从指定的提交中拷贝文件到暂存区域和工作目录。比如,git checkout HEAD~ foo.c
会将提交节点HEAD~中的foo.c
复制到工作目录并且加到暂存区域中。(如果命令中没有指定提交节点,则会从暂存区域中拷贝内容。)注意当前分支不会发生变化。
当不指定文件名,而是给出一个(本地)分支时,那么HEAD标识会移动到那个分支(也就是说,我们“切换”到那个分支了),然后暂存区域和工作目录中的内容会和HEAD对应的提交节点一致。新提交节点(下图中的a47c3)中的所有文件都会被复制(到暂存区域和工作目录中);只存在于老的提交节点(ed489)中的文件会被删除;不属于上述两者的文件会被忽略,不受影响v
如果既没有指定文件名,也没有指定分支名,而是一个标签、远程分支、SHA-1值或者是像main~3类似的东西,就得到一个匿名分支,称作detached HEAD(被分离的HEAD标识)。这样可以很方便地在历史版本之间互相切换。比如说你想要编译1.6.6.1版本的git,你可以运行git checkout v1.6.6.1
(这是一个标签,而非分支名),编译,安装,然后切换回另一个分支,比如说git checkout main
。然而,当提交操作涉及到“分离的HEAD”时,其行为会略有不同,
1.2.4、HEAD标识处于分离状态时的提交操作
当HEAD处于分离状态(不依附于任一分支)时,提交操作可以正常进行,但是不会更新任何已命名的分支。
一旦此后你切换到别的分支,比如说main,那么这个提交节点(可能)再也不会被引用到,然后就会被丢弃掉了。注意这个命令之后就不会有东西引用2eecb。
但是,如果你想保存这个状态,可以用命令git checkout -b name
来创建一个新的分支。
1.2.5、reset
reset命令把当前分支指向另一个位置,并且有选择的变动工作目录和索引。也用来在从历史仓库中复制文件到索引,而不动工作目录。
如果不给选项,那么当前分支指向到那个提交。如果用--hard
选项,那么工作目录也更新,如果用--soft
选项,那么都不变。
如果没有给出提交点的版本号,那么默认用HEAD。这样,分支指向不变,但是索引会回滚到最后一次提交,如果用--hard
选项,工作目录也同样。
如果给了文件名(或者 -p
选项), 那么工作效果和带文件名的checkout差不多,除了索引被更新。
1.2.6、merge
merge 命令把不同分支合并起来。合并前,索引必须和当前提交相同。如果另一个分支是当前提交的祖父节点,那么合并命令将什么也不做。 另一种情况是如果当前提交是另一个分支的祖父节点,就导致fast-forward合并。指向只是简单的移动,并生成一个新的提交。
否则就是一次真正的合并。默认把当前提交(ed489 如下所示)和另一个提交(33104)以及他们的共同祖父节点(b325c)进行一次三方合并。结果是先保存当前目录和索引,然后和父节点33104一起做一次新提交。
2、分支管理
一个分支代表一条独立的开发线。使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作。(Git 分支实际上是指向更改快照的指针。)
2.1、创建和切换分支
# 创建分支
git branch <分支名>
# 切换分支
git checkout <分支名>
# 创建并切换分支
git checkout -b <分支名>
克隆并创建分支(将克隆的添加到另一个分支)
git clone <远程仓库地址> -b <分支名>
2.2、标签
2.2.1、创建标签
git tag [-a] <标签名> [-m "标签描述"] [提交ID]
# 填上【-a】为其创建一个带注解的标签,默认打开编辑器,【-m】后可以在命令行输入
#提交ID,默认当前分支即HEAD
2.2.2、查看标签和标签信息
# 查看标签
git tag
# 查看标签信息
git show <标签名>
# 查看远程标签
git ls-remote --tag <远程仓库名:默认:origin>
2.2.3、推送标签到远程仓库:
git push origin <标签名>
# 推送所有标签
git push origin --tags
2.2.4、删除标签
# 删除本地标签
git tag -d <标签名>
# 删除远程标签
git push origin --delete <标签名>
3、远程
3.1、查看远程仓库git remote
# 列出所有远程仓库
git remote
# 显示所有远程地址
git remote -v
# 显示某个远程仓库的信息
git remote show <远程仓库名:默认:origin>
3.2、关联远程
# 关联远程仓库
git remote add <远程仓库名:一般用origin> <远程仓库地址>
# eg
git remote add origin https://github.com/zqx1473/git_project.git
# 删除远程仓库关联
git remote rm <远程仓库名>
# 关联关系重命名
git remote rename <原名字> <新名字>
3.3、远程仓库的推送删除和重命名:git push
git push 命令用于从将本地的分支版本上传到远程并合并。
# 推送
git push <远程主机名> <本地分支名>:<远程分支名>
# 本地分支名与远程分支名相同,则可以省略冒号
git push <远程主机名> <本地分支名>
# 强制推送
# 本地版本与远程版本有差异,但又要强制推送可以使用 --force 参数
git push --force <远程主机名> <本地分支名>:<远程分支名>
# or
git push -f <远程主机名> <本地分支名>:<远程分支名>
# 删除远程分支
git push <远程主机名> --delete <远程分支名>
# eg
git push origin --delete master
# 重命名远程分支
git push origin --delete <远程分支名>
git push origin <本地分支名>:<远程分支名>
4、拓展功能
4.1、git忽略文件
有的时候, 我们某些文件/文件夹, 不想让git进行跟踪管理
需要在【.git】文件夹旁边来个叫【.gitignore】(固定的名字)的忽略文件夹并写入忽略规则。
(.gitignore文件本身应该提交给git管理)
.gitignore 只能忽略那些没有被追踪的文件,所以先纳入版本管理后写入.gitignore是无效
当然,可以先清除本地缓存之后再加入
git rm -r --cached
git add .
git status
4.1.1、编写规则
# “#”表示注释
# 忽略指定文件
ignore.txt
# 忽略文件夹
foldername
# 忽略文件夹下某个文件
foldername/filename
# 忽略某类文件
*.txt
# 排除(如指定了*.txt忽略,不想让其中的【ignore】忽略,可使用)
!ignore.txt
4.1.2、检查信息
检查是否忽略
git check-ignore <文件名>
查看具体信息
git check-ignore -v [文件名]
4.2、配置别名
偷懒福音
$ git config --global alias.st status
$ git config --global alias.co checkout
$ git config --global alias.ci commit
$ git config --global alias.br branch
咯,还是在这个文件里面
————————————————
参考: