
Git 版本控制系统入门教程
Git 版本控制系统的基础知识与核心操作。内容包括 Git 的安装配置、工作区与版本库概念、基本工作流程(add/commit/log)、分支管理(创建/切换/合并/冲突解决)、远程仓库操作(克隆/推送/拉取)以及多人协作流程。此外还涵盖了标签管理、版本回退及撤销修改等实用技巧,帮助开发者掌握代码版本控制技能。

Git 版本控制系统的基础知识与核心操作。内容包括 Git 的安装配置、工作区与版本库概念、基本工作流程(add/commit/log)、分支管理(创建/切换/合并/冲突解决)、远程仓库操作(克隆/推送/拉取)以及多人协作流程。此外还涵盖了标签管理、版本回退及撤销修改等实用技巧,帮助开发者掌握代码版本控制技能。


Git 是一个开源的分布式版本控制系统,用于高效地跟踪和管理项目代码的变更历史(不仅仅是代码,还有其它格式也是可以的)。
在学习或者是工作的时候,比如编写各种文档,为了防止文档丢失,更改失误,我们不得不复制出一个副本,保留历史记录,方便找回历史记录。例如:
'设计文档-v1'
'设计文档-v2'
'设计文档-v3'
'设计文档 - 确定版'
'设计文档 - 最终版'
每个版本有各自的内容,但最终会只有一份文档是需要被使用的,在此之前的工作都需要这些不同版本的报告,于是每次都是复制粘贴副本,文件就越来越多,不仅文件多,更重要的是,随着版本数量的不断增多,我们可能记不太清每一个版本具体修改了哪些内容,文档如此,我们编写的项目代码也如此!
那么,如何解决呢?
答:版本控制器,记录每次修改以及版本迭代的一个管理系统。目前,最主流的版本控制器就是 Git,可以控制电脑上所有格式的文件。
为了能够更方便管理这些不同版本的文件,便有了版本控制器!所谓的版本控制器,就是能让你了解到一个文件的历史,以及它的发展过程的系统。通俗的讲就是一个可以记录工程的每一次改动和版本迭代的一个管理系统,同时也方便多人协同作业。目前最主流的版本控制器就是 Git,Git 可以控制电脑上所有格式的文件,例如 doc、excel、dwg、dgn、rvt 等等,对于我们开发人员来说,Git 最重要的就是可以帮助我们管理软件开发项目中的源代码文件!
【注意事项】
所有的版本控制系统,Git 也不例外,其实只能跟踪文本文件的改动,比如 txt 文件,网页,所有的程序代码等等,版本控制系统可以告诉你每次的改动,比如在第 10 行加了"name",在第 12 行删除了一个"Windows",而图片、视频等这些二进制文件,虽然也能由版本控制系统管理,但没办法跟踪文件的变化,只能把二进制文件每次改动串起来,即只知道图片从 90KB 改成了 100KB,但到底改了啥,版本控制系统无法记录。

接下来,我们来进行实操!安装 Git。
Git 是开放源代码的代码托管工具,最早是在 Linux 下开发的,当然,最开始也只能应用于 Linux 平台,后面慢慢的被移植到 Windows 下,现在 Git 可以在 Linux、Unix、Mac 和 Windows 这几大平台上正常运行了。
这里介绍 Ubuntu 下的安装。
在 Ubuntu 安装 git 相当简单,一起来看看!
git --version
Command 'git' not found, but can be installed with: sudo apt install git
sudo apt-get install git -y(在安装过程中,出现了图形化界面,回车即可)git --version,就可以看到 git 版本号啦!此时,安装完成。Git 官网直接下载:Git 下载官网


下载完成后,找到下载到的文件,进行双击进行安装

非常简单的,按照指示点下一步就好。

输入:git --version,出现对应安装的 git 版本号,就是安装成功啦!

Git 的安装是很简单的,现在我们来看看 Git 的初始化与配置。
可以将仓库理解成是进行版本控制的一个文件目录,如果我们想要对文件进行版本控制,就必须先创建一个仓库出来!
创建一个 Git 本地仓库对应的命令为 git init,注意命令要在文件目录下执行,例如:


当安装 Git 后首先要做的事情就是设置你的用户名称和 e-mail 地址,这是非常非常重要的,配置命令为:
git config [--global] user.name "Your Name"
git config [--global] user.email "[email protected]"
# 把 Your Name 改成你的用户名
# 把 [email protected] 改成你的邮箱的格式,只要格式正确即可
注意 --global 是一个可选项,如果使用了该选项,就表示这台机器上所有的 Git 仓库都会使用这个配置,如果你希望在不同仓库中使用不同的 name 或 e-mail,即可以不要 --global 选项,但需要注意的是,执行命令时必须要在仓库里面。
查看配置命令为:
git config -l
删除对应的配置命令为:
git config [--global] --unset user.name
git config [--global] --unset user.email

git add 命令,暂存区目录树的文件索引会被更新git commit 时,master 分支会做相应的更新,可以简单理解为暂存区的目录树才会被真正写到版本库中由上述描述我们便能得知:通过新建或粘贴进目录的文件,并不能称之为向仓库中新增文件,而只是在工作区新增了文件。必须要通过使用
git add和git commit命令才能将文件添加到仓库中进行管理!!!
添加文件
在包含 .git 的目录下新建一个 ReadMe 文件,我们可以使用 git add 命令可以将文件添加到暂存区:
• 添加一个或多个文件到暂存区:
git add [file1] [file2] ...
• 添加指定目录到暂存区,包括子目录:git add [dir]
• 添加当前目录下的所有文件改动到暂存区:git add .
再使用
git commit命令将暂存区内容添加到本地仓库中:
• 提交暂存区全部内容到本地仓库中:git commit -m "message"
• 提交暂存区的指定文件到仓库区:git commit [file1] [file2] ... -m "message"
注意: git commit 后面的 -m 选项,要跟上描述本次提交的 message,由用户自己完成,这部分内容绝对不能省略,并要好好描述,是用来记录你的提交细节,是给我们人看的。
例如:

我们还可以多次 add 不同的文件,而只 commit 一次便可以提交所有文件,是因为需要提交的文件是通通被 add 到暂存区中,然后一次性 commit 暂存区的所有修改。如:

Git 工作流程:
git add 将修改添加到暂存区,准备提交git commit 将暂存区的修改保存到本地仓库,生成一个提交记录(上述介绍的是本地仓库)git push 将本地提交推送到远程仓库,如 Gitee、GitHub(后续介绍如何连远程仓库)截至目前为止,我们已经能够将代码直接提交至本地仓库了。我们可以使用 git log 命令,来查看下历史提交记录:

该命令显示从最近到最远的提交日志,并且可以看到我们 commit 时的日志消息。
如果嫌输出信息太多,看得眼花缭乱的,可以试试加上 --pretty=oneline 参数:

需要说明的是,我们看到的一大串类似 5a250e...2111e0 的是每次提交的 commit id(版本号),Git 的 commit id 不是 1,2,3……递增的数字,而是一个 SHA1 计算出来的一个非常大的数字,用十六进制表示。
查看.git 文件
先来看看我们的 .git 的目录结构:


而默认的 master 分支,其实就是:

打印的 5a250e9e1895753939dfcf9cba0719ee6d2111e0 是什么东西呢?保存的就是当前最新的 commit id。
git add 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,就位于 ".git/objects" 目录下,让我们来看看这些对象有何用处:
查找 object 时要将 commit id 分成 2 部分,其前 2 位是文件夹名称,后 38 位是文件名称。
找到这个文件之后,一般不能直接看到里面是什么,该类文件是经过 sha(安全哈希算法)加密过的文件,好在我们可以使用 git cat-file 命令来查看版本库对象的内容:

其中,还有一行 tree c9b796e175c00c170f3e2b54ce4e2dd73cf43af9,我们使用同样的方法,看看结果:

再看 ReadMe 对应的 a0423896973644771497bdc03eb99d5281615b51:

总结一下,在本地的 git 仓库中,有几个文件或目录很特殊
• index: 暂存区,git add 后会更新该内容。
• HEAD: 默认指向 master 分支的一个指针。
• refs/heads/master: 文件里保存当前 master 分支的最新 commit id。
• objects: 包含了创建的各种版本库对象及内容,可以简单理解为放了 git 维护的所有修改。

修改文件
Git 比其他版本控制系统设计得优秀,因为 Git 跟踪并管理的是修改,而非文件。
什么是修改?比如你新增了一行,这就是一个修改,删除了一行,也是一个修改,更改了某些字符,也是一个修改,删了一些又加了一些,也是一个修改,甚至创建一个新文件,也算一个修改。
让我们将 ReadMe 文件进行一次修改:

此时,仓库中的 ReadMe 和我们工作区的 ReadMe 是不同的,如何查看当前仓库的状态呢?git status 命令用于查看在你上次提交之后是否有对文件进行再次修改。

上面的结果告诉我们,ReadMe 被修改过了,但还没有完成添加与提交。

目前,我们只知道文件被修改了,如果能知道具体哪些地方被修改了,就更好了。有人会说,我刚改的我知道呀!可是,你还记得你三天前写了什么代码吗?或者没写?
git diff [file] 命令用来显示暂存区和工作区文件的差异,显示的格式正是 Unix 通用的 diff 格式。也可以使用 git diff HEAD -- [file] 命令来查看版本库和工作区文件的区别。
知道了对 ReadMe 做了什么修改后,再把它提交到本地仓库就放心多了。

git add 之后,就没有看到上面 no changes added to commit (use "git add" and/or "git commit -a") 的消息了。接下来让我们继续 git commit 即可:

版本回退
执行 git reset 命令用于回退版本,可以指定退回某一次提交的版本。要解释一下'回退'本质是将版本库中的内容进行回退,工作区或暂存区是否回退由命令参数决定:
git reset命令语法格式为:git reset [--soft | --mixed | --hard] [HEAD]• HEAD 说明:
◦ 可直接写成 commit id,表示指定退回的版本
◦ HEAD 表示当前版本
◦ HEAD^ 上一个版本
◦ HEAD^^ 上上一个版本
◦ 以此类推...
• 可以使用 ~ 数字表示:
◦ HEAD0 表示当前版本1 上一个版本
◦ HEAD
◦ HEAD^2 上上一个版本
◦ 以此类推...
值得说的是,Git 的版本回退速度非常快,因为 Git 在内部有个指向当前分支(此处是 master)的 HEAD 指针,refs/heads/master 文件里保存当前 master 分支的最新 commit id。当我们回退版本的时候,Git 仅仅是给 refs/heads/master 中存储一个特定的 version,可以简单理解成如下示意图:


【操作一】 提交 version3 后,发现 version3 编写有误,想回退到 version2,重新基于 version2 开始写,这里希望工作区的内容也回退到 version2 版本,因此需要 --hard 参数,如下:

可以看到 Read 文件的内容,已经回退到 version2 了,使用 git log 查看提交日志,也发现 HEAD 指向了 version2。
【操作二】 后悔回退到 version2,想再回到 version3
可以继续使用 git reset 命令,回退到 version3 版本,but 我们必须要拿到 version3 的 commit id 去指定回退的版本,从上图中,看到 git log 并不能打印出 version3 的 commit id,如果运气好的话,可以在终端找之前的记录,运气不好的话,commit id 已经被我们搞丢啦,不过不用担心!Git 提供了一个 git reflog 命令,可以补救一下,该命令用来记录本地的每一次命令!!!

【操作三】 在实际开发中,由于长时间开发,导致 commit id 早就找不到了,但是又想回到 version3,貌似现在不可能~
我们要知道 Git 版本回退速度非常快,因为 Git 在内部有个指向当前分支,这里是 HEAD 指针默认指向 master 分支,在.git 隐藏文件中 refs/heads/master 文件里面保存了当前 master 分支的最新 commit id,当我们在回退版本的时候,Git 仅仅是给 refs/heads/master 中存储一个特定的 version,可以简单理解为下图:

可以查看 refs/heads/master 文件内容,保存了最新的 commit id,如下:
如果是操作二,回退到 version3 版本,则保存的 commit id 为 version3 的
撤销修改
情况一:对于工作区的代码,还没有 add

万幸!才写了一行内容,就发现需要删除了,万一写了很多,一直都没有提交,可能都忘记自己新增的哪些内容了,那如何删除呢?
Git 为我们提供了更好的方式!!!
我们可以使用
git checkout -- [file]命令让工作区的文件回到最近一次 add 或 commit 时的状态。要注意git checkout -- [file]命令中的--很重要,切记不要省略,一旦省略,该命令就变为其他意思了

情况二:已经 add,但没有 commit
add 后还是保存到了暂存区呢?怎么撤销呢?
让我们来回忆一下学过的
git reset回退命令,该命令如果使用--mixed参数,可以将暂存区的内容退回为指定的版本内容,但工作区文件保持不变。那我们就可以回退下暂存区的内容了!!

我们可以将版本回退到当前版本库版本
git reset --mixed HEAD File
git reset --hard HEAD File
情况三:已经 add,并且也 commit 了
不要担心,我们可以git reset --hard HEAD^回退到上一个版本!不过,这是有条件的,就是你还没有把自己的本地版本库推送到远程。

删除本地仓库中的文件
在 Git 中,删除也是一个修改操作
下面演示删除 file4 文件:
使用 rm file4?

这样直接删除是没有用的,此时只是删除了工作区的 file4,git status 会告诉你哪些文件被删除了,但是,这个时候,工作区和版本库就不一致了,要删除文件,除了要删除工作区的文件,还要清除版本库的文件
到这里,有两种情况:
【情况一】确实需要从版本库删除该文件
使用 git rm [文件名],将文件从工作区和暂存区中删除,并且 commit ~

【情况二】删错了
使用 git checkout -- file4 来恢复,删除也是修改哦,这是刚刚学过的命令~


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

每次提交,master 分支都会向前移动一步,这样,随着你不断提交,master 分支的线也越来越长,而 HEAD 只要一直指向 master 分支即可指向当前分支。
通过查看当前的版本库,我们也能清晰的理出思路:
cat .git/HEAD ---》ref: refs/heads/master
cat .git/refs/heads/master ----》5476bdeb12510f7cd72ac4766db7988925ebd302
创建分支
Git 支持我们查看或创建其他分支,在这里我们来创建第一个自己的分支 dev,对应的命令为:
git branch #查看当前本地所有分支 ----》* master
git branch dev #新建分支 dev
git branch ---》dev ---》* master
当我们创建新的分支后,Git 新建了一个指针叫 dev,* 表示当前 HEAD 指向的分支是 master 分支。另外,可以通过目录结构发现,新的 dev 分支:
ls .git/refs/heads/ ---》dev master
cat .git/refs/heads/* -》5476bdeb12510f7cd72ac4766db7988925ebd302 -》5476bdeb12510f7cd72ac4766db7988925ebd302
发现目前 dev 和 master 指向同一个修改。并且也可以验证下 HEAD 目前是指向 master 的。
cat .git/HEAD ---》ref: refs/heads/master

切换分支
那如何切换到 dev 分支下进行开发呢?使用 git checkout 命令即可完成切换,示例如下:
git checkout dev -》Switched to branch 'dev'
git branch -》* dev -》master
cat .git/HEAD -》ref: refs/heads/dev

我们发现 HEAD 已经指向了 dev,就表示我们已经成功的切换到了 dev 上!
接下来,在 dev 分支下修改 ReadMe 文件,新增一行内容,并进行一次提交操作:
vim ReadMe
cat ReadMe -》hello bit -》write aaa for new branch
git add .
git commit -m"modify ReadMe" -》[dev 3740dce] modify ReadMe -》1 file changed, 1 insertion(+)
现在,dev 分支的工作完成,我们就可以切换回 master 分支:
git checkout master -》Switched to branch 'master'
cat ReadMe -》hello bit
切换回 master 分支后,发现 ReadMe 文件中新增的内容不见了!!
但是在 dev 分支上,内容还在。为什么会出现这个现象呢?我们来看看 dev 分支和 master 分支指向,发现两者指向的提交是不一样的:
因为我们是在 dev 分支上提交的,而 master 分支此刻的提交点并没有变,此时的状态如图如下所示:

当切换到 master 分支之时,HEAD 就指向了 master,当然看不到提交了!
合并分支
为了在 master 主分支上能看到新的提交,就需要将 dev 分支合并到 master 分支,示例如下:
git branch -》* dev -》master
git checkout master # 切换到 master 上进行合并 -》Switched to branch 'master'
git merge dev # 合并 dev 分支 -》Updating 16623e1..3740dce -》Fast-forward -》ReadMe | 1 + -》1 file changed, 1 insertion(+)
cat ReadMe -》hello bit -》write aaa for new branch
git merge 命令用于合并指定分支到当前分支。合并后,master 就能看到 dev 分支提交的内容了。此时的状态如图如下所示。

Fast-forward 代表'快进模式',也就是直接把 master 指向 dev 的当前提交,所以合并速度非常快。 当然,也不是每次合并都能 Fast-forward。 删除分支 合并完成后,dev 分支对于我们来说就没用了,那么 dev 分支就可以被删除掉,注意如果当前正处于某分支下,就不能删除当前分支,如:
git branch -》* dev -》master
git branch -d dev -》error: Cannot delete branch 'dev' checked out at '/home/user/gitcode'
而可以在其他分支下删除当前分支,如
git checkout master
Switched to branch 'master'
git branch -d dev Deleted branch dev (was bdaf528).

因为创建、合并和删除分支非常快,所以 Git 鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在 master 分支上工作效果是一样的,但过程更安全。
合并冲突
可是,在实际分支合并的时候,并不是想合并就能合并成功的,有时候可能会遇到代码冲突的问题。为了演示这问题,创建一个新的分支 dev1,并切换至目标分支,我们可以使用 git checkout -b dev1 一步完成创建并切换的动作,示例如下
git checkout -b dev1 Switched to a new branch 'dev1'
git branch * dev1 master
在 dev1 分支下修改 ReadMe 文件,更改文件内容如下,并进行一次提交,如:
cat ReadMe hello bit write bbb for new branch # 将 aaa 该为 bbb
git add .
git commit -m"modify ReadMe" [dev1 0854245] modify ReadMe 1 file changed, 1 insertion(+), 1 deletion(-)
切换至 master 分支,观察 ReadMe 文件内容:
git checkout master
Switched to branch 'master'cat ReadMe
hello bit
write aaa for new branch
我们发现,切回来之后,文件内容由变成了老的版本,这种现象很正常,我们现在也完全能理解。
此时在 master 分支上,我们对 ReadMe 文件再进行一次修改,并进行提交,如下:
[user@server repo]$ git branch dev1 * master [user@server repo]$ vim ReadMe [user@server repo]$ cat ReadMe hello bit write ccc for new branch [user@server repo]$ git add . [user@server repo]$ git commit -m"modify ReadMe" [master c10f6d0] modify ReadMe 1 file changed, 1 insertion(+), 1 deletion(-)
现在,master 分支和 dev1 分支各自都分别有新的提交,变成了这样:

这种情况下,Git 只能试图把各自的修改合并起来,但这种合并就可能会有冲突,如下所示:
[user@server repo]$ git merge dev1 Auto-merging ReadMe CONFLICT (content): Merge conflict in ReadMe Automatic merge failed; fix conflicts and then commit the result. [user@server repo]$ 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: ReadMe no changes added to commit (use "git add" and/or "git commit -a")
发现 ReadMe 文件有冲突后,可以直接查看文件内容,要说的是 Git 会用 <<<<<<<,=======,>>>>>>> 来标记出不同分支的冲突内容,如下所示:

此时我们必须要手动调整冲突代码,并需要再次提交修正后的结果!!(再次提交很重要,切勿忘记)

到这里冲突就解决完成,此时的状态变成了:

分支管理策略 通常合并分支时,如果可能,Git 会采用 Fast forward 模式。还记得如果我们采用 Fast forward 模式之后,形成的合并结果是什么呢?

在这种 Fast forward 模式下,删除分支后,查看分支历史时,会丢掉分支信息,看不出来最新提交到底是 merge 进来的还是正常提交的。 但在合并冲突部分,我们也看到通过解决冲突问题,会再一次进行新的提交,得到的最终状态为:

那么这就不是 Fast forward 模式了,这样的好处是,从分支历史上就可以看出分支信息。例如我们现在已经删除了在合并冲突部分创建的 dev1 分支,但依旧能看到 master 其实是由其他分支合并得到

Git 支持我们强制禁用 Fast forward 模式,那么就会在 merge 时生成一个新的 commit,这样,从分支历史上就可以看出分支信息
git merge --no-ff -m "msg" branch_name
bug 分支 假如我们现在正在 dev2 分支上进行开发,开发到一半,突然发现 master 分支上面有 bug,需要解决。在 Git 中,每个 bug 都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。 可现在 dev2 的代码在工作区中开发了一半,还无法提交,怎么办?
Git 提供了 git stash 命令,可以将当前的工作区信息进行储藏,被储藏的内容可以在将来某个时间恢复出来。
[user@server repo]$ git stash
Saved working directory and index state WIP on dev2: 41b082f modify ReadMe
[user@server repo]$ git status
On branch dev2
nothing to commit, working tree clean
用 git status 查看工作区,就是干净的(除非有没有被 Git 管理的文件),因此可以放心地创建分支来修复 bug。
储藏 dev2 工作区之后,由于我们要基于 master 分支修复 bug,所以需要切回 master 分支,再新建临时分支来修复 bug,示例如下:
[user@server repo]$ git checkout master # 切回 master Switched to branch 'master' [user@server repo]$ git checkout -b fix_bug # 新建并切换到 fix_bug 分支 Switched to a new branch 'fix_bug' [user@server repo]$ vim ReadMe [user@server repo]$ cat ReadMe hello bit write bbb for new branch a,b,c,d,e # 修复 bug--忘记写 e [user@server repo]$ git add ReadMe # 重新 add,commit [user@server repo]$ git commit -m"fix bug" [fix_bug 4bbc0c4] fix bug 1 file changed, 1 insertion(+), 1 deletion(-)
修复完成后,切换到 master 分支,并完成合并,最后删除 fix_bug 分支。 至此,bug 的修复工作已经做完了,我们还要继续回到 dev2 分支进行开发。切换回 dev2 分支
[user@server repo]$ git checkout dev2 Switched to branch 'dev2' [user@server repo]$ git status On branch dev2 nothing to commit, working tree clean
工作区是干净的,刚才的工作现场存到哪去了?用 git stash list 命令看看
[user@server repo]$ git stash list stash@{0}: WIP on dev2: 41b082f modify ReadMe
工作现场还在,Git 把 stash 内容存在某个地方了,但是需要恢复一下,如何恢复现场呢?我们可以使用 git stash pop 命令,恢复的同时会把 stash 也删了,示例如下:
[user@server repo]$ git stash pop On branch dev2 Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: ReadMe no changes added to commit (use "git add" and/or "git commit -a") Dropped refs/stash@{0} (4f873250b3503695efd26976676767676767676767)
再次查看的时候,我们已经发现已经没有现场可以恢复了。 但我们注意到了,修复 bug 的内容,并没有在 dev2 上显示。此时的状态图为:

Master 分支目前最新的提交,是要领先于新建 dev2 时基于的 master 分支的提交的,所以我们在 dev2 中当然看不见修复 bug 的相关代码。 我们的最终目的是要让 master 合并 dev2 分支的,那么正常情况下我们切回 master 分支直接合并即可,但这样其实是有一定风险的。 是因为在合并分支时可能会有冲突,而代码冲突需要我们手动解决(在 master 上解决)。我们无法保证对于冲突问题可以正确地一次性解决掉,因为在实际的项目中,代码冲突不只一两行那么简单,有可能几十上百行,甚至更多,解决的过程中难免手误出错,导致错误的代码被合并到 master 上。此时的状态为:

解决这个问题的一个好的建议就是:最好在自己的分支上合并下 master,再让 master 去合并 dev,这样做的目的是有冲突可以在本地分支解决并进行测试,而不影响 master。此时的状态为:


下面演示在 gitee 上创建远程仓库


上面的.gitignore 是为了在上传时过滤掉不重要的文件,分支模型选单分支模型就够用了,或者选生产/开发模型。 当然,如果创建仓库的时候没有添加.gitignore 文件,可以在本地仓库创建.gitignore 文件


下面仅介绍两种方式:HTTPS,SSH



SSH


然后查看是否有 id_rsa 和 id_rsa.pub 这两个文件

如果没有的话,需要创建 ssh.key
ssh-keygen -t rsa -C "[email protected]"
注意:上面的邮箱要和 gitee 上绑定的邮箱一致
如果有的话,打开看一下

将上面的内容全部复制下来,然后再打开 gitee 的设置

配置 SSH 公钥



git add
git commit -m "XXX"
git push
当我们从远程仓库克隆后,实际上 Git 会自动把本地的 master 分支和远程的 master 分支对应起来,并且,远程仓库的默认名称是 origin。在本地我们可以使用 git remote 命令,来查看远程库的信息,如:
git remote
或者,用 git remote -v 显示更详细的信息:
git remote -v origin
提交时要注意,如果我们之前设置过全局的 name 和 e-mail,这两项配置需要和 gitee 上配置的用户名和邮箱一致,否则会出错。或者从来没有设置过全局的 name 和 e-mail,那么我们第一次提交时也会报错。这就需要我们重新配置下了,同样要注意需要和 gitee 上配置的用户名和邮箱一致。如何配置已讲过,在这里就不再赘述。
到这里我们已经将内容提交至本地仓库中,如何将本地仓库的内容推送至远程仓库呢,需要使用 git push 命令,该命令用于将本地的分支版本上传到远程并合并,命令格式如下:

拉取远程仓库内容

在我们使用 Git 期间,有些命令敲的时候着实让人头疼(太长了。。),幸运的是,git 支持对命令进行简化!
举个例子,将 git status 简化为 git st,对应的命令为:
git config --global alias.st status
--global 参数是全局参数,也就是这些命令在这台电脑的所有 Git 仓库下都有用。如果不加,那只针对当前的仓库起作用。
标签 tag,可以简单的理解为是对某次 commit 的一个标识,相当于起了一个别名。例如,在项目发布某个版本的时候,针对最后一次 commit 起一个 v1.0 这样的标签来标识里程碑的意义。 这有什么用呢?相较于难以记住的 commit id,tag 很好的解决这个问题,因为 tag 一定要给人容易记住,且有意义的名字。当我们需要回退到某个重要版本时,直接使用标签就能很快定位到。
创建标签
在 Git 中打标签非常简单,首先,切换到需要打标签的分支上
然后,敲命令 git tag [name] 就可以打一个新标签
可以用命令 git tag 查看所有标签
可以用 git show [tagname] 查看标签信息。

当然,并非只能给最新的提交打标签,使用如下命令查看 commit id,然后在 git tag [版本] [commit id]

Git 还提供可以创建带有说明的标签,用-a 指定标签名,-m 指定说明文字,格式为:
git tag -a [name] -m "XXX" [commit_id]
删除标签

因为创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。
如果要推送某个标签到远程,使用命令
git push origin <tagname>
当然,如果你本地有很多标签,也可以一次性的全部推送到远端:
git push origin --tags
git push origin --delete <标签名>
目标:远程 master 分支下 file.txt 文件新增代码'aaa','bbb'
实现:由开发者 1 新增 aaa,开发者 2 新增 bbb
条件:在一个分支下协作完成
我们创建一个分支 dev,在分支 dev 上完成这些操作
git branch 查看本地分支,只有一个 master;git branch -r 查看远程分支,我们可以看到远程里面也只有 master,没有新创建的 dev

将 dev 分支从远程拉取下来

在 windows 上面模拟开发者 2,首先需要将仓库克隆到 windows 下,随便选取一个目录,shift + 右键


此时我们准备工作完成,接下来我们让开发者 1 新增 aaa,开发者 2 新增 bbb

我们可以分别用 Linux 机器和 Windows 机器来模拟开发者 1 和开发者 2,依旧是采用我们上面已经创建的仓库 remote-repo。
开发者 1 创建一个分支 dev,然后开发者 1 和开发者 2 都同时在这个分支上进行操作。

👉 你在哪个分支上工作,就从那个分支 push 自己:

打开 bash 进行 clone 远程仓库:

当 clone 的时候,本地仓库就只有 master 分支,那么就要获取 dev 分支。如果本地还没有 dev,Git 会自动从远程的 origin/dev 创建一个对应的本地分支,并自动追踪它。
git checkout -b dev origin/dev

将本地 dev 分支和远程的 dev 分支进行建立链接,开发者 2 的本地也具有 dev 分支了。


切换到开发者 2 中,可以看到正常的进行对 file.txt 文件进行修改,可是 push 的时候却发生错误,提示当前的本地与远程仓库有区别!

我们应该先进行 pull 来更新本地仓库!
git pull origin dev
再次 push 又会发现失败,出现合并冲突问题,需要手动进行解决!!!

解决完冲突后,这里要特别注意,要重新进行 add . 和 commit -m 来重新进行推送,再次进行 push 就可以上传成功,开发者 2 新添加的 bbb 内容成功推送。
此时可以在远程的 dev 分支上看到我们想要得到的结果:file.txt 文件内有开发者 1 添加的'aaa',有开发者 2 添加的 bbb。
接下来就可以用 master 来合并 dev 分支!!!

可以看到 master 分支上没有这两行代码!
开发者 1 和开发者 2 在远程仓库创建一个 Pull Request,提交合并请求。


dev 分支和 master 分支上,执行如下命令:git checkout master
git merge dev
git push origin master
由于在 master 上进行 merge dev,可能会导致冲突,因此应该在本地 dev 上进行 merge master。这样就算有冲突,也可以在本地解决。解决完冲突后,再用 master 来 merge dev,就不会有问题。
步骤如下:


这样就可以看到 master 分支上的 file.txt 被同步更新了。

完成后,可以同时让开发者 1 和开发者 2 对 dev 分支进行删除。


要保证本地的 master 是最新的,先 pull 操作,然后再次创建 dev 分支。



可以看到每次开发都是自己创建的分支,然后进行 push,每次都能成功,不会遇到冲突的问题。因为我们是在最新的 master 上创建的分支,然后自己创建的分支只有自己开发的时候能够用上,所以不会出现 push 冲突的问题。
突然,开发者 2 生病了,开发者 1 需要担起开发 feature-2 分支的重任!这时需要从远程拉取 feature-2 分支进行开发。此时,我们又回到了多人开发一中的情形,开发者 1 和开发者 2 在同一个分支开发。
使用如下命令拉取远程 feature-2 分支的内容:
git pull origin feature-2
拉取到远程的 origin/feature-2 分支后,本地没有这个分支,所以需要创建并切换至 feature-2 分支。
git checkout -b feature-2 origin/feature-2


此时,开发者 1 就能够在 feature-2 分支上继续开发

现在就是又遇到了合并 feature-1 的问题,为了避免冲突 我们就还是再 feature-1 分支上来合并 master

每次 feature-1 合并 master 之前 就要先保证 master 是最新的,所以要切换到 master 进行 pull 再用 master 进行合并 merge


当我们 merge master 的时候跳转到当前页面就说明没用任何问题,没用产生冲突,ctrl + x 就会退出该页面!

最后,开发者 1 和开发者 2 将各自的 feature-1 和 feature-2 分支合并到 master 分支上。


删除远程分支后,本地仍然可以看到已删除的远程分支。此时,可以使用以下命令移除远程已删除的分支记录:

git remote prune origin

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online