在国外的网站做推广,网络建设费是什么,wordpress wiki知识库,网站公司建站目录
一、Git安装
1.1Linux Centos安装
二、Git基本操作
2.1创建 Git 本地仓库
2.2配置Git
三、认识工作区、暂存区、版本库
3.1添加文件#xff08;场景一#xff09;
3.2修改文件
3.3版本回退
四、撤销修改
4.1情况一#xff1a;对于工作区的代码#xff0c;还…目录
一、Git安装
1.1Linux Centos安装
二、Git基本操作
2.1创建 Git 本地仓库
2.2配置Git
三、认识工作区、暂存区、版本库
3.1添加文件场景一
3.2修改文件
3.3版本回退
四、撤销修改
4.1情况一对于工作区的代码还没有add
4.2情况二已经add 但没有commit
4.3情况三已经add 并且也commit 了
五、删除文件
六、分支管理
6.1理解分支
6.1创建分支 6.2切换分支
6.3合并分支
6.4删除分支
6.5合并冲突
七、分支管理策略
7.1分支管理策略
7.2分支策略
7.3bug 分支
7.4删除临时分支
7.5小结
八、远程操作
8.1理解分布式版本控制系统
九、远程仓库
9.1新建远程仓库
9.2克隆远程仓库
9.3向远程仓库推送
9.4拉取远程仓库
十、配置 Git
10.1忽略特殊文件
10.2给命令配置别名
十一、标签管理
11.1理解标签
11.2创建标签
11.3操作标签 背景知识 我们在编写各种文档时为了防止文档丢失更改失误失误后能恢复到原来的版本不得不复制出一个副本。每个版本有各自的内容但最终会只有一份报告需要被我们使用 。但在此之前的工作都需要这些不同版本的报告于是每次都是复制粘贴副本产出的文件就越来越多文件多不是问题问题是随着版本数量的不断增多你还记得这些版本各自都是修改了什么吗文档如此我们写的项目代码也是存在这个问题的 如何解决--版本控制器 为了能够更方便我们管理这些不同版本的文件便有了版本控制器。所谓的版本控制器就是能让你了解到一个文件的历史以及它的发展过程的系统。通俗的讲就是一个可以记录工程的每一次改动和版本迭代的一个管理系统同时也方便多人协同作业。目前最主流的版本控制器就是 Git 。Git 可以控制电脑上所有格式的文件例如 doc、excel、dwg、dgn、rvt等等。对于我们开发人员来说Git 最重要的就是可以帮助我们管理软件开发项目中的源代码 文件 注意事项 所有的版本控制系统Git 也不例外其实只能跟踪文本文件的改动比如 TXT 文件网页所有的程序代码等等。版本控制系统可以告诉你每次的改动比如在第5行加了一个单词“Linux”在第8行删了一个单词 “Windows”。而图片、视频这些二进制文件虽然也能由版本控制系统管理但没法跟踪文件的变化只能把二进制文件每次改动串起来也就是只知道图片从100KB改成了120KB但到底改了啥版本控制系统不知道也没法知道。 一、Git安装
1.1Linux Centos安装
安装 Git:
sudo 1 yum -y install git
查看 Git 安装的版本
git --version 二、Git基本操作
2.1创建 Git 本地仓库
仓库是进行版本控制的一个文件目录。我们要想对文件进行版本控制就必须先创建一个仓库出来。创建一个 Git 本地仓库对应的命令为 git init 注意命令要在文件目录下执行例如
hyb139-159-150-152:~/gitcode$ pwd
/home/hyb/gitcode
hyb139-159-150-152:~/gitcode$ git init
Initialized empty Git repository in /home/hyb/gitcode/.git/
hyb139-159-150-152:~/gitcode$ ll -a
total 12
drwxrwxr-x 3 hyb hyb 4096 May 5 15:49 ./
drwxr-xr-x 13 hyb hyb 4096 May 5 15:47 ../
drwxrwxr-x 7 hyb hyb 4096 May 5 15:49 .git/
我们发现当前目录下多了一个.git 的隐藏文件 .git 目录是 Git 来跟踪管理仓库的不要手动 修改这个目录里面的文件不然改乱了就把 Git 仓库给破坏了。
查看.git文件夹中的内容
hyb139-159-150-152:~/gitcode$ tree .git/
.git/
├── branches
├── config
├── description
├── HEAD
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── fsmonitor-watchman.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── pre-merge-commit.sample
│ ├── prepare-commit-msg.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ ├── pre-receive.sample
│ └── update.sample
├── info
│ └── exclude
├── objects
│ ├── info
│ └── pack
└── refs
├── heads
└── tags
9 directories, 16 files
2.2配置Git
当安装 Git 后首先要做的事情是设置你的 用户名称 和 e-mail 地址这是非常重要的。配置命令为
git config [--global] user.name Your Name
git config [--global] user.email emailexample.com
# 把 Your Name 改成你的昵称
# 把 emailexample.com 改成邮箱的格式只要格式正确即可。
# --global:将配置项生效于所有当前机器的git仓库中全局
其中 --global(--global:将配置项生效于所有当前机器的git仓库中全局) 是一个可选项。如果使用了该选项表示这台机器上所有的 Git 仓库都会使用这个配置。如果你希望在不同仓库中使用不同的 name 或 e-mail 可以不要 --global 选项但要注意的是执行命令时必须要在仓库里。
查看配置是否成功
git config -l
删除对应的配置命令为
git config [--global] --unset user.name
git config [--global] --unset user.email 三、认识工作区、暂存区、版本库
工作区是在电脑上你要写代码或文件的目录。
暂存区英文叫 stage 或 index。一般存放在 .git 目录下的 index 文件.git/index中我们 把暂存区有时也叫作索引index。
版本库又名仓库英文名 repository 。工作区有一个隐藏目录 .git 它不算工作区而是 Git 的版本库。这个版本库里面的所有文件都可以被 Git 管理起来每个文件的修改、删除Git 都能跟踪以便任何时刻都可以追踪历史或者在将来某个时刻可以“还原”。 图中左侧为工作区右侧为版本库。Git 的版本库里存了很多东西其中最重要的就是暂存区。在创建 Git 版本库时Git 会为我们自动创建一个唯一的 master 分支以及指向 master 的一个指针叫 HEAD。分支和HEAD的概念后面再说当对工作区修改或新增的文件执行 git add 命令时暂存区目录树的文件索引会被更新。当执行提交操作git commit 时master 分支会做相应的更新可以简单理解为暂存区的目录树才会被真正写到版本库中。由上述描述我们便能得知通过新建或粘贴进目录的文件并不能称之为向仓库中新增文件而只是在工作区新增了文件。必须要通过使用 git add 和 git commit 命令才能将文件添加到仓库中进行管理
3.1添加文件场景一
在包含 .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由用户自己完成这部分内容绝对不能省略并要好好描述是用来记录你的提交细节是给我们人看的。 hyb139-159-150-152:~/gitcode$ vim ReadMe
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello bit
hyb139-159-150-152:~/gitcode$ git add ReadMe
hyb139-159-150-152:~/gitcode$ git commit -m commit my first file
[master (root-commit) c614289] commit my first file
1 file changed, 2 insertions()
create mode 100644 ReadMe git commit 命令执行成功后会告诉我们1个文件被改动就是我们新添加的ReadMe文件插 入了两行内容ReadMe有两行内容。我们还可以多次 add 不同的文件而只 commit 一次便可以提交所有文件是因为需要提交的文件是通通被 add 到暂存区中然后一次性 commit 暂存区的所有修改。如
hyb139-159-150-152:~/gitcode$ touch file1 file2 file3
hyb139-159-150-152:~/gitcode$ git add file1
hyb139-159-150-152:~/gitcode$ git add file2
hyb139-159-150-152:~/gitcode$ git add file3
hyb139-159-150-152:~/gitcode$ git commit -m add 3 files
[master 23807c5] add 3 files
3 files changed, 0 insertions(), 0 deletions(-)
create mode 100644 file1
create mode 100644 file2
create mode 100644 file3
截至目前为止我们已经更够将代码直接提交至本地仓库了。我们可以使用 git log 命令来查看 下历史提交记录 hyb139-159-150-152:~/gitcode$ git log
commit 23807c536969cd886c4fb624b997ca575756eed6 (HEAD - master)
Author: hyb91 2689241679qq.com
Date: Sat May 6 11:27:32 2023 0800
add 3 files
commit c61428926f3853d4ec6dde904415b0e6c1dabcc6
Author: hyb91 2689241679qq.com
Date: Sat May 6 11:25:50 2023 0800
commit my first file 该命令显示从最近到最远的提交日志并且可以看到我们 commit 时的日志消息。 如果嫌输出信息太多看得眼花缭乱的可以试试加上--prettyoneline 参数
yb139-159-150-152:~/gitcode$ git log --prettyoneline
23807c536969cd886c4fb624b997ca575756eed6 (HEAD - master) add 3 files
c61428926f3853d4ec6dde904415b0e6c1dabcc6 commit my first file需要说明的是我们看到的一大串类似23807c5...56eed6 的是每次提交的 commit id 版本 号Git 的commit id 不是123……递增的数字而是一个 SHA1 计算出来的一个非常大的数 字用十六进制表示你看到的commit id 和我的肯定不一样以你自己的为准。 index 就是我们的暂存区 HEAD 就是我们的默认指向master分支的指针 hyb139-159-150-152:~/gitcode$ cat .git/HEAD
ref: refs/heads/master而默认的 master分支就是 hyb139-159-150-152:~/gitcode$ cat .git/refs/heads/master
23807c536969cd886c4fb624b997ca575756eed6 objects 为 Git 的对象库里面包含了创建的各种版本库对象及内容。当执行 git add 命令 时暂存区的目录树被更新同时工作区修改或新增的文件内容被写入到对象库中的一个新的 对象中就位于 .git/objects 目录下让我们来看看这些对象有何用处
hyb139-159-150-152:~/gitcode$ ls .git/objects/
23 83 8f 9c c6 e6 info pack查找 object 时要将 commit id 分成2部分其前2位是文件夹名称后38位是文件名称。 找到这个文件之后一般不能直接看到里面是什么该类文件是经过 sha 安全哈希算法加密过的文件好在我们可以使用 git cat-file 命令来查看版本库对象的内容
hyb139-159-150-152:~/gitcode$ git cat-file -p 23807c536969cd886c4fb624b997ca575
tree 830a8c9feefbdc098bbae2cdc25e5034ce1920d7
parent c61428926f3853d4ec6dde904415b0e6c1dabcc6
author hyb91 2689241679qq.com 1683343652 0800
committer hyb91 2689241679qq.com 1683343652 0800
add 3 files
# 这就是我们最近一次的提交
其中还有一行 tree 830a8c9feefbdc098bbae2cdc25e5034ce1920d7 ,我们使用同样的方 法看看结果
hyb139-159-150-152:~/gitcode$ git cat-file -p 830a8c9feefbdc098bbae2cdc25e5034c
100644 blob 9c9e1f0f6bff3015df71a0963004476f5e6cfd54 ReadMe
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 file1
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 file2
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 file3在看 ReadMe 对应的 9c9e1f0f6bff3015df71a0963004476f5e6cfd54
hyb139-159-150-152:~/gitcode$ git cat-file -p 9c9e1f0f6bff3015df71a0963004476f5
hello bit
hello bit
# 这是我们对ReadMe做的修改被git记录了下来 总结一下在本地的 git 仓库中有几个文件或者目录很特殊 index: 暂存区 git add 后会更新该内容。HEAD: 默认指向 master 分支的一个指针。refs/heads/master: 文件里保存当前 master 分支的最新commit id 。objects: 包含了创建的各种版本库对象及内容可以简单理解为放了 git 维护的所有修改。 3.2修改文件
Git 比其他版本控制系统设计得优秀因为 Git 跟踪并管理的是修改而非文件。 什么是修改比如你新增了一行这就是一个修改删除了一行也是一个修改更改了某些字符也是一个修改删了一些又加了一些也是一个修改甚至创建一个新文件也算一个修改。 git diff [file] 命令用来显示暂存区和工作区文件的差异显示的格式正是Unix通用的diff格式。也可以使用 git diff HEAD -- [file] 命令来查看版本库和工作区文件的区别。知道了对 ReadMe 做了什么修改后再把它提交到本地仓库就放心多了。 3.3版本回退
之前我们也提到过Git 能够管理文件的历史版本这也是版本控制器重要的能力。如果有一天你发现之前前的工作做的出现了很大的问题需要在某个特定的历史版本重新开始这个时候就需要版本回退的功能了。
执行 git reset 命令用于回退版本可以指定退回某一次提交的版本。要解释一下“回退”本质是 要将版本库中的内容进行回退工作区或暂存区是否回退由命令参数决定
git reset 命令语法格式为 git reset [--soft | --mixed | --hard] [HEAD]
--mixed 为默认选项使用时可以不用带该参数。该参数将暂存区的内容退回为指定提交版本内容工作区文件保持不变。--soft 参数对于工作区和暂存区的内容都不变只是将版本库回退到某个指定版本。--hard 参数将暂存区与工作区都退回到指定版本。切记工作区有未提交的代码时不要用这个命令因为工作区会回滚你没有提交的代码就再也找不回了所以使用该参数前一定要慎重。 HEAD 说明 ◦ 可直接写成 commit id表示指定退回的版本 ◦ HEAD 表示当前版本 ◦ HEAD^ 上一个版本 ◦ HEAD^^ 上上一个版本 ◦ 以此类推... • 可以使用 数字表示 ◦ HEAD~0 表示当前版本 ◦ HEAD~1 上一个版本 ◦ HEAD^2 上上一个版本 ◦ 以此类推... 为了便于表述方便测试回退功能我们先做一些准备工作更新3个版本的 ReadMe并分别进行3次提交如下所示
# 第一次修改提交
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hyb139-159-150-152:~/gitcode$ git add ReadMe
hyb139-159-150-152:~/gitcode$ git commit -madd version1
[master cff9d1e] add version1
1 file changed, 1 insertion()
# 第二次修改提交
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hyb139-159-150-152:~/gitcode$ git add ReadMe
hyb139-159-150-152:~/gitcode$ git commit -madd version2
1 file changed, 1 insertion()
# 第三次修改提交
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
hyb139-159-150-152:~/gitcode$ git add ReadMe
hyb139-159-150-152:~/gitcode$ git commit -madd version3
[master d95c13f] add version3
1 file changed, 1 insertion()
# 查看历史提交记录
hyb139-159-150-152:~/gitcode$ git log --prettyoneline
d95c13ffc878a55a25a3d04e22abfc7d2e3e1383 (HEAD - master) add version3
14c12c32464d6ead7159f5c24e786ce450c899dd add version2
cff9d1e019333318156f8c7d356a78c9e49a6e7b add version1
...
现在如果我们在提交完 version3 后 发现 version 3 编写错误想回退到 version2重新基于 version 2 开始编写。由于我们在这里希望的是将工作区的内容也回退到 version 2 版本所以需 要用到 --hard 参数示例如下
hyb139-159-150-152:~/gitcode$ git log --prettyoneline
d95c13ffc878a55a25a3d04e22abfc7d2e3e1383 (HEAD - master) add version3
14c12c32464d6ead7159f5c24e786ce450c899dd add version2
cff9d1e019333318156f8c7d356a78c9e49a6e7b add version1
...
hyb139-159-150-152:~/gitcode$ git reset --hard 14c12c32464d6ead7159f5c24e786ce4
HEAD is now at 14c12c3 add version2
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
我们惊奇的发现此时ReadMe 文件的内容已经回退到 version2 了当前我们再次用 git log 查看一下提交日志发现HEAD 指向了version2如下所示
hyb139-159-150-152:~/gitcode$ git log --prettyoneline
14c12c32464d6ead7159f5c24e786ce450c899dd (HEAD - master) add version2
cff9d1e019333318156f8c7d356a78c9e49a6e7b add version1
...
到这里一般回退功能就演示完了但现在如果我后悔了想再回到 version 3 怎么办我们可以继续使用 git reset 命令回退到 version 3 版本但我们必须要拿到 version 3 的 commit id 去指定回退的版本。 但我们看到了 git log 并不能打印出 version 3 的commit id 运气好的话我们可以从终端 上去找找之前的记录运气不好的话 commit id 已经被我们搞丢了。
Git 还提供了一个git reflog 命令能补救一下该命令用来记录本地的每一次命令。
hyb139-159-150-152:~/gitcode$ git reflog
14c12c3 (HEAD - master) HEAD{0}: reset: moving to 14c12c32464d6ead7159f5c24e78
d95c13f HEAD{1}: commit: add version3
14c12c3 (HEAD - master) HEAD{2}: commit: add version2
cff9d1e HEAD{3}: commit: add version1
94da695 HEAD{4}: commit: add modify ReadMe file
23807c5 HEAD{5}: commit: add 3 files
c614289 HEAD{6}: commit (initial): commit my first file
这样你就可以很方便的找到你的所有操作记录了但d95c13f 这个是啥东西这个是 version 3 的commit id 的部分。没错Git 版本回退的时候也可以使用部分commit id 来代表目标版 本。示例如下
# 回退到v3
hyb139-159-150-152:~/gitcode$ git reset --hard d95c13f
HEAD is now at d95c13f add version3
# 查看工作区
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
# 查看log
hyb139-159-150-152:~/gitcode$ git log --prettyoneline
d95c13ffc878a55a25a3d04e22abfc7d2e3e1383 (HEAD - master) add version3
14c12c32464d6ead7159f5c24e786ce450c899dd add version2
cff9d1e019333318156f8c7d356a78c9e49a6e7b add version1
94da6950d27e623c0368b22f1ffc4bff761b5b00 add modify ReadMe file
23807c536969cd886c4fb624b997ca575756eed6 add 3 files
c61428926f3853d4ec6dde904415b0e6c1dabcc6 commit my first file
可往往是理想很丰满现实很骨感。在实际开发中由于长时间的开发了导致 commit id 早就找 不到了可突然某一天我又想回退到 version3那该如何操作呢貌似现在不可能了。。。
值得说的是Git 的版本回退速度非常快因为 Git 在内部有个指向当前分支此处是master的 HEAD 指针 refs/heads/master 文件里保存当前 master 分支的最新commit id 。当我们 在回退版本的时候Git 仅仅是给 refs/heads/master 中存储一个特定的version可以简单理解 成如下示意图 四、撤销修改
如果我们在我们的工作区写了很长时间代码越写越写不下去觉得自己写的实在是垃圾想恢复到上一个版本。
4.1情况一对于工作区的代码还没有add
# 向ReadMe中新增一行代码
hyb139-159-150-152:~/gitcode$ git status
On branch master
nothing to commit, working tree clean
hyb139-159-150-152:~/gitcode$ vim ReadMe
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
This piece of code is like shit #新增代码
hyb139-159-150-152:~/gitcode$ git status
On branch master
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)
# 直接删除代码
hyb139-159-150-152:~/gitcode$ vim ReadMe
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
hyb139-159-150-152:~/gitcode$ git status
On branch master
nothing to commit, working tree clean
辛亏我们工作效率不高才写了一行代码就发现不行了要是你写了3天一直都没有提交该怎么删掉呢你自己都忘了自己新增过哪些有同学说我可以git diff xxx 一下看看差别在删啊 那你肯定又要花3天时间删代码了并且很大的概率还会改出bug。一周过去了你怎么向你的老板交代呢 Git 其实还为我们提供了更好的方式我们可以使用 git checkout -- [file] 命令让工作区的 文件回到最近一次 add 或 commit 时的状态。 要注意git checkout -- [file] 命令中的 -- 很重要切记不要省略一旦省略该命令就变为其他意思了后面我们再说。示例如下
# 向ReadMe中新增一行代码
hyb139-159-150-152:~/gitcode$ vim ReadMe
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
This piece of code is like shit #新增代码
# 恢复到上一次 add 或 commit
hyb139-159-150-152:~/gitcode$ git checkout -- ReadMe
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
4.2情况二已经add 但没有commit
add 后还是保存到了暂存区呢怎么撤销呢
# 向ReadMe中新增一行代码
hyb139-159-150-152:~/gitcode$ vim ReadMe
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
This piece of code is like shit #新增代码
# add 存入暂存区
hyb139-159-150-152:~/gitcode$ git add ReadMe
hyb139-159-150-152:~/gitcode$ git status
On branch master
Changes to be committed:
(use git restore --staged file... to unstage)
modified: ReadMe
让我们来回忆一下学过的git reset 回退命令该命令如果使用 --mixed 参数可以将暂存区 的内容退回为指定的版本内容但工作区文件保持不变。那我们就可以回退下暂存区的内容了示例如下
# --mixed 是默认参数使用时可以省略
hyb139-159-150-152:~/gitcode$ git reset HEAD ReadMe
Unstaged changes after reset:
M ReadMe
hyb139-159-150-152:~/gitcode$ git status
On branch master
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)
hyb139-159-150-152:~/gitcode$ git checkout -- ReadMe
hyb139-159-150-152:~/gitcode$ git status
On branch master
nothing to commit, working tree clean
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
4.3情况三已经add 并且也commit 了
不要担心我们可以git reset --hard HEAD^ 回退到上一个版本不过这是有条件的就是 你还没有把自己的本地版本库推送到远程。还记得Git是分布式版本控制系统吗我们后面会讲到远程版本库一旦你推送到远程版本库你就真的惨了……
# 向ReadMe中新增一行代码
hyb139-159-150-152:~/gitcode$ vim ReadMe
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
This piece of code is like shit #新增代码
# 提交
hyb139-159-150-152:~/gitcode$ git add ReadMe
hyb139-159-150-152:~/gitcode$ git commit -mtest quash
[master 5f71ae1] test quash
1 file changed, 1 insertion()
# 回退
hyb139-159-150-152:~/gitcode$ git reset --hard HEAD^
HEAD is now at 144a3f8 add file
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3 五、删除文件
在 Git 中删除也是一个修改操作我们实战一下, 如果要删除file5 文件怎么搞呢如果你这样 做了:
hyb139-159-150-152:~/gitcode$ ls
file1 file2 file3 file4 file5 ReadMe
hyb139-159-150-152:~/gitcode$ rm file5
但这样直接删除是没有用的反而徒增烦恼 git status 命令会立刻告诉你哪些文件被删除了:
hyb139-159-150-152:~/gitcode$ git status
On branch master
Changes not staged for commit:
(use git add/rm file... to update what will be committed)
(use git restore file... to discard changes in working directory)
deleted: file5
no changes added to commit (use git add and/or git commit -a)
此时工作区和版本库就不一致了要删文件目前除了要删工作区的文件还要清除版本库的文 件。 一般走到这里有两种可能: • 确实要从版本库中删除该文件 • 不小心删错了 对第二种情况很明显误删需要使用 git 来进行恢复很简单,我们刚学过删除也是修改:
hyb139-159-150-152:~/gitcode$ git checkout -- file5
hyb139-159-150-152:~/gitcode$ ls
file1 file2 file3 file4 file5 ReadMe
对于第一种情况很明显是没有删完我们只删除了工作区的文件。这时就需要使用 git rm 将文 件从暂存区和工作区中删除并且 commit
hyb139-159-150-152:~/gitcode$ git rm file5
rm file5
hyb139-159-150-152:~/gitcode$ git status
On branch master
Changes to be committed:
(use git restore --staged file... to unstage)
deleted: file5
hyb139-159-150-152:~/gitcode$ git commit -mdeleted file5
[master 5476bde] deleted file5
1 file changed, 0 insertions(), 0 deletions(-)
delete mode 100644 file5
hyb139-159-150-152:~/gitcode$ git status
On branch master
nothing to commit, working tree clean
现在文件就从版本库中被删除了。 六、分支管理
6.1理解分支
每次提交Git都把它们串成一条时间线这条时间线就可以理解为是一个分支。截止到目前只有一条时间线在Git里这个分支叫主分支即 master 分支。再来理解一下HEADHEAD 严格来说不是指向提交而是指向mastermaster才是指向提交的所以HEAD 指向的就是当前分支。 每次提交master分支都会向前移动一步这样随着你不断提交master分支的线也越来越长,而HEAD只要一直指向master分支即可指向当前分支。通过查看当前的版本库我们也能清晰的理出思路:
hyb139-159-150-152:~/gitcode$ cat .git/HEAD
ref: refs/heads/master
hyb139-159-150-152:~/gitcode$ cat .git/refs/heads/master
5476bdeb12510f7cd72ac4766db7988925ebd302
6.1创建分支 通过git branch:查看当前分支git会默认给我们创建一个主分支 在这里我们来创建第一个自己的分支 dev 对应的命令为
hyb139-159-150-152:~/gitcode$ git branch #查看当前本地所有分支
* master
hyb139-159-150-152:~/gitcode$ git branch dev #新建分支dev
hyb139-159-150-152:~/gitcode$ git branch
dev
* master 基于最新一次提交创建的分支 6.2切换分支
那如何切换到 dev 分支下进行开发呢使用 git checkout 命令即可完成切换示例如下
hyb139-159-150-152:~/gitcode$ git checkout dev
Switched to branch dev
hyb139-159-150-152:~/gitcode$ git branch
* dev
master
hyb139-159-150-152:~/gitcode$ cat .git/HEAD
ref: refs/heads/dev 我们发现 HEAD 已经指向了 dev就表示我们已经成功的切换到了 dev 上 接下来在dev 分支下修改 ReadMe 文件新增一行内容并进行一次提交操作
hyb139-159-150-152:~/gitcode$ vim ReadMe
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
write aaa for new branch
hyb139-159-150-152:~/gitcode$ git add .
hyb139-159-150-152:~/gitcode$ git commit -mmodify ReadMe
[dev 3740dce] modify ReadMe
1 file changed, 1 insertion() 现在dev 分支的工作完成我们就可以切换回 master 分支
hyb139-159-150-152:~/gitcode$ git checkout master
Switched to branch master
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
切换回 master 分支后发现ReadMe文件中新增的内容不见了赶紧再切回 dev 看看:
hyb139-159-150-152:~/gitcode$ git checkout dev
Switched to branch dev
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
write aaa for new branch 在 dev 分支上内容还在。为什么会出现这个现象呢我们来看看 dev 分支和 master 分支指向发现两者指向的提交是不一样的
hyb139-159-150-152:~/gitcode$ cat .git/refs/heads/dev
bdaf528ffbb8e05aee34d37685408f0e315e31a4
hyb139-159-150-152:~/gitcode$ cat .git/refs/heads/master
5476bdeb12510f7cd72ac4766db7988925ebd302
看到这里就能明白了因为我们是在dev分支上提交的而master分支此刻的提交点并没有变此时的状态如图如下所示。 当切换到 master 分支之时HEAD 就指向了 master当然看不到提交了
6.3合并分支
为了在 master 主分支上能看到新的提交就需要将dev 分支合并到master 分支示例如下
hyb139-159-150-152:~/gitcode$ git branch
* dev
master
hyb139-159-150-152:~/gitcode$ git checkout master # 切换到 master 上进行合并
Switched to branch master
hyb139-159-150-152:~/gitcode$ git merge dev # 合并 dev 分支
Updating 16623e1..3740dce
Fast-forward
ReadMe | 1
1 file changed, 1 insertion()
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
write aaa for new branch
git merge 命令用于合并指定分支到当前分支。合并后master 就能看到 dev 分支提交的内容 了。此时的状态如图如下所示。 Fast-forward 代表“快进模式”也就是直接把master指向dev的当前提交所以合并速度非常快。 当然也不是每次合并都能 Fast-forward我们后面会讲其他方式的合并。
6.4删除分支
合并完成后, dev 分支对于我们来说就没用了 那么dev分支就可以被删除掉注意如果当前正处于某分支下就不能删除当前分支如
hyb139-159-150-152:~/gitcode$ git branch
* dev
master
hyb139-159-150-152:~/gitcode$ git branch -d dev
error: Cannot delete branch dev checked out at /home/hyb/gitcode
而可以在其他分支下删除当前分支如
hyb139-159-150-152:~/gitcode$ git checkout master
Switched to branch master
hyb139-159-150-152:~/gitcode$ git branch -d dev
Deleted branch dev (was bdaf528).
hyb139-159-150-152:~/gitcode$ git branch
* master
此时的状态如图如下所示。 因为创建、合并和删除分支非常快所以Git鼓励你使用分支完成某个任务合并后再删掉分支这和直接在master分支上工作效果是一样的但过程更安全。
6.5合并冲突
可是在实际分支合并的时候并不是想合并就能合并成功的有时候可能会遇到代码冲突的问题。为了演示这问题创建一个新的分支 dev1 并切换至目标分支我们可以使用 git checkout - b dev1 一步完成创建并切换的动作示例如下
hyb139-159-150-152:~/gitcode$ git checkout -b dev1
Switched to a new branch dev1
hyb139-159-150-152:~/gitcode$ git branch
* dev1
master
在dev1 分支下修改ReadMe 文件更改文件内容如下并进行一次提交如
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
write bbb for new branch # 将 aaa 该为 bbb
hyb139-159-150-152:~/gitcode$ git add .
hyb139-159-150-152:~/gitcode$ git commit -mmodify ReadMe
[dev1 0854245] modify ReadMe
1 file changed, 1 insertion(), 1 deletion(-) 切换至 master 分支观察ReadMe 文件内容:
hyb139-159-150-152:~/gitcode$ git checkout master
Switched to branch master
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
write aaa for new branch
我们发现切回来之后文件内容由变成了老的版本这种现象很正常我们现在也完全能理解。 此时在 master 分支上我们对 ReadMe 文件再进行一次修改并进行提交如下
hyb139-159-150-152:~/gitcode$ git branch
dev1
* master
hyb139-159-150-152:~/gitcode$ vim ReadMe
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
write ccc for new branch
hyb139-159-150-152:~/gitcode$ git add .
hyb139-159-150-152:~/gitcode$ git commit -mmodify ReadMe
[master c10f6d0] modify ReadMe
1 file changed, 1 insertion(), 1 deletion(-) 现在 master 分支和dev1 分支各自都分别有新的提交变成了这样 这种情况下Git 只能试图把各自的修改合并起来但这种合并就可能会有冲突如下所示
hyb139-159-150-152:~/gitcode$ git merge dev1
Auto-merging ReadMe
CONFLICT (content): Merge conflict in ReadMe
Automatic merge failed; fix conflicts and then commit the result.
hyb139-159-150-152:~/gitcode$ 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 会用 来标记出不同分支的冲突内容如下所示
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3HEAD
write ccc for new branchwrite bbb for new branchdev1
此时我们必须要手动调整冲突代码并需要再次提交修正后的结果再次提交很重要切勿忘 记
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
write bbb for new branch
hyb139-159-150-152:~/gitcode$ git add .
hyb139-159-150-152:~/gitcode$ git commit -mmerge ReadMe
[master 2976afc] merge ReadMe 到这里冲突就解决完成此时的状态变成了 用带参数的 git log也可以看到分支的合并情况具体大家可以自行搜索git log 的用法:
hyb139-159-150-152:~/gitcode$ git log --graph --prettyoneline --abbrev-commit
* 2976afc (HEAD - master) merge ReadMe
|\
| * c594fd1 (dev1) modify ReadMe
* | c10f6d0 modify ReadMe
|/ 最后不要忘记 dev1 分支使用完毕后就可以删除了
hyb139-159-150-152:~/gitcode$ git branch
* master
hyb139-159-150-152:~/gitcode$ git branch -d dev1
Deleted branch dev1 (was c594fd1). 七、分支管理策略
7.1分支管理策略
通常合并分支时如果可能Git 会采用 Fast forward 模式。还记得如果我们采用 Fast forward 模式之后形成的合并结果是什么呢回顾一下 在这种Fast forward 模式下删除分支后查看分支历史时会丢掉分支信息看不出来最新提 交到底是 merge 进来的还是正常提交的。但在合并冲突部分我们也看到通过解决冲突问题会再进行一次新的提交得到的最终状态为 那么这就不是Fast forward 模式了这样的好处是从分支历史上就可以看出分支信息。例如我们现在已经删除了在合并冲突部分创建的dev1 分支但依旧能看到 master 其实是由其他分支合并 得到
hyb139-159-150-152:~/gitcode$ git log --graph --prettyoneline --abbrev-commit
* 2976afc (HEAD - master) merge ReadMe
|\
| * c594fd1 modify ReadMe
* | c10f6d0 modify ReadMe
|/Git 支持我们强制禁用 Fast forward 模式那么就会在 merge 时生成一个新的commit 这样 从分支历史上就可以看出分支信息。下面我们实战一下--no-ff 方式的 git merge 。首先创建新的分支 dev2 并切换至新的分支:
hyb139-159-150-152:~/gitcode$ git checkout -b dev2
Switched to a new branch dev2
修改ReadMe 文件并提交一个新的commit :
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
write bbb for new branch
a,b,c,d
hyb139-159-150-152:~/gitcode$ git add .
hyb139-159-150-152:~/gitcode$ git commit -mmodify ReadMe
[dev2 41b082f] modify ReadMe
1 file changed, 1 insertion() 切回master 分支开始合并:
hyb139-159-150-152:~/gitcode$ git checkout master
Switched to branch master
hyb139-159-150-152:~/gitcode$ git merge --no-ff -m merge with no-ff dev2
Merge made by the recursive strategy.
ReadMe | 1
1 file changed, 1 insertion()
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
write bbb for new branch
a,b,c,d 请注意--no-ff 参数表示禁用 Fast forward 模式。禁用 Fast forward 模式后合并会创建 一个新的commit 所以加上-m 参数把描述写进去。合并后查看分支历史
hyb139-159-150-152:~/gitcode$ git log --graph --prettyoneline --abbrev-commit
* 5bd16b4 (HEAD - master) merge with no-ff
|\
| * 41b082f (dev2) modify ReadMe
|/
可以看到不使用 Fast forward 模式merge后就像这样 所以在合并分支时加上--no-ff 参数就可以用普通模式合并合并后的历史有分支能看出来曾 经做过合并而 fast forward 合并就看不出来曾经做过合并。
7.2分支策略
在实际开发中我们应该按照几个基本原则进行分支管理首先master分支应该是非常稳定的也就是仅用来发布新版本平时不能在上面干活那在哪干活呢干活都在dev分支上也就是说dev分支是不稳定的到某个时候比如1.0版本发布时再把dev分支合并到master上在master分支发布1.0版本你和你的小伙伴们每个人都在dev分支上干活每个人都有自己的分支时不时地往dev分支上合并就可以了。所以团队合作的分支看起来就像这样 7.3bug 分支
假如我们现在正在 dev2 分支上进行开发开发到一半突然发现master 分支上面有 bug需要 解决。在Git中每个 bug 都可以通过一个新的临时分支来修复修复后合并分支然后将临时分支删除。可现在 dev2 的代码在工作区中开发了一半还无法提交怎么办例如
hyb139-159-150-152:~/gitcode$ git branch
* dev2
master
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
write bbb for new branch
a,b,c,d
i am coding ...
hyb139-159-150-152:~/gitcode$ git status
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) Git 提供了git stash 命令可以将当前的工作区信息进行储藏被储藏的内容可以在将来某个时 间恢复出来。
hyb139-159-150-152:~/gitcode$ git stash
Saved working directory and index state WIP on dev2: 41b082f modify ReadMe
hyb139-159-150-152:~/gitcode$ git status
On branch dev2
nothing to commit, working tree clean
用 git status 查看工作区就是干净的除非有没有被 Git 管理的文件因此可以放心地创建分 支来修复bug。储藏dev2 工作区之后由于我们要基于master分支修复 bug所以需要切回master 分支再新建临时分支来修复 bug示例如下
hyb139-159-150-152:~/gitcode$ git checkout master # 切回master
Switched to branch master
hyb139-159-150-152:~/gitcode$ git checkout -b fix_bug # 新建并切换到 fix_bug 分支
Switched to a new branch fix_bug
hyb139-159-150-152:~/gitcode$ vim ReadMe
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
write bbb for new branch
a,b,c,d,e # 修复bug--忘记写e
hyb139-159-150-152:~/gitcode$ git add ReadMe # 重新addcommit
hyb139-159-150-152:~/gitcode$ git commit -mfix bug
[fix_bug 4bbc0c4] fix bug
1 file changed, 1 insertion(), 1 deletion(-)
修复完成后切换到master 分支并完成合并最后删除fix_bug 分支
hyb139-159-150-152:~/gitcode$ git checkout master
Switched to branch master
hyb139-159-150-152:~/gitcode$ git merge --no-ff -mmerge fix_bug branch fix_bu
Merge made by the recursive strategy.
ReadMe | 2 -
1 file changed, 1 insertion(), 1 deletion(-)
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
write bbb for new branch
a,b,c,d,e
hyb139-159-150-152:~/gitcode$ git branch -d fix_bug
Deleted branch fix_bug (was 4bbc0c4). 至此bug 的修复工作已经做完了我们还要继续回到 dev2 分支进行开发。切换回dev2 分支
hyb139-159-150-152:~/gitcode$ git checkout dev2
Switched to branch dev2
hyb139-159-150-152:~/gitcode$ git status
On branch dev2
nothing to commit, working tree clean
工作区是干净的刚才的工作现场存到哪去了用 git stash list 命令看看
hyb139-159-150-152:~/gitcode$ git stash list
stash{0}: WIP on dev2: 41b082f modify ReadMe 工作现场还在Git 把 stash 内容存在某个地方了但是需要恢复一下如何恢复现场呢我们可以使用 git stash pop 命令恢复的同时会把 stash 也删了示例如下
hyb139-159-150-152:~/gitcode$ 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} (4f873250b3503687b5efd26196776aee7e3724c2)
再次查看的时候我们已经发现已经没有现场可以恢复了
hyb139-159-150-152:~/gitcode$ git stash list
hyb139-159-150-152:~/gitcode$ 另外恢复现场也可以采用 git stash apply 恢复但是恢复后stash内容并不删除你需要 用 git stash drop 来删除你可以多次stash恢复的时候先用 git stash list 查看然后恢复指定的stash用命令git stash apply stash{0} ,这部分请同学们自行使用。恢复完代码之后我们便可以继续完成开发开发完成后便可以进行提交例如
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
write bbb for new branch
a,b,c,d
i am coding ... Done!
hyb139-159-150-152:~/gitcode$ git add .
hyb139-159-150-152:~/gitcode$ git commit -mmodify ReadMe
[dev2 ed0916d] modify ReadMe
1 file changed, 1 insertion()
但我们注意到了修复 bug 的内容并没有在 dev2 上显示。此时的状态图为 Master 分支目前最新的提交是要领先于新建dev2 时基于的master 分支的提交的所以我们 在dev2 中当然看不见修复 bug 的相关代码。
我们的最终目的是要让master 合并dev2 分支的那么正常情况下我们切回master 分支直接合 并即可但这样其实是有一定风险的。是因为在合并分支时可能会有冲突而代码冲突需要我们手动解决在master 上解决。我们无法保证对于冲突问题可以正确地一次性解决掉因为在实际的项目中代码冲突不只一两行那么简单有可能几十上百行甚至更多解决的过程中难免手误出错导致错误的代码被合并到master 上。此时的状态为 解决这个问题的一个好的建议就是最好在自己的分支上合并下master 再让master 去合并 dev 这样做的目的是有冲突可以在本地分支解决并进行测试而不影响master 。此时的状态 为 对应的实操演示如下要说明的是以下演示的merge操作没有使用 --no-ff 但上述的图示是 禁用 Fast forward 了模式后得出的主要是为了方便解释问题。
# dev 合并 master
hyb139-159-150-152:~/gitcode$ git branch
* dev2
master
hyb139-159-150-152:~/gitcode$ git merge master
Auto-merging ReadMe
CONFLICT (content): Merge conflict in ReadMe
Automatic merge failed; fix conflicts and then commit the result.
# 发生冲突
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
write bbb for new branchHEAD
a,b,c,d
i am coding ... Done!a,b,c,d,emaster
# 解决冲突并重新提交
hyb139-159-150-152:~/gitcode$ vim ReadMe
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
write bbb for new branch
a,b,c,d,e
i am coding ... Done!
hyb139-159-150-152:~/gitcode$ git add .
hyb139-159-150-152:~/gitcode$ git commit -mmerge master
[dev2 447d29f] merge master
hyb139-159-150-152:~/gitcode$ git status
On branch dev2
nothing to commit, working tree clean
# 切回master
hyb139-159-150-152:~/gitcode$ git checkout master
Switched to branch master
# master 合并 dev2---无需解决冲突
hyb139-159-150-152:~/gitcode$ git merge dev2
Updating 193421f..447d29f
Fast-forward
ReadMe | 1
1 file changed, 1 insertion()
hyb139-159-150-152:~/gitcode$ git status
On branch master
nothing to commit, working tree clean
# 删除 dev2 分支
hyb139-159-150-152:~/gitcode$ git branch -d dev2
Deleted branch dev2 (was 447d29f). 7.4删除临时分支
软件开发中总有无穷无尽的新的功能要不断添加进来。 添加一个新功能时你肯定不希望因为一些实验性质的代码把主分支搞乱了所以每添加一个新功能最好新建一个分支我们可以将其称之为 feature 分支在上面开发完成后合并最 后删除该 feature 分支。可是如果我们今天正在某个 feature 分支上开发了一半被产品经理突然叫停说是要停止新功能的开发。虽然白干了但是这个 feature 分支还是必须就地销毁留着无用了。这时使用传统的git branch -d 命令删除分支的方法是不行的。演示如下 # 新增并切换到 dev3 分支
hyb139-159-150-152:~/gitcode$ git checkout -b dev3
Switched to a new branch dev3
# 开始开发新功能并提交
hyb139-159-150-152:~/gitcode$ vim ReadMe
hyb139-159-150-152:~/gitcode$ cat ReadMe
hello bit
hello git
hello world
hello version1
hello version2
hello version3
write bbb for new branch
a,b,c,d,e
i am coding ... Done!
i am writing new features ...
hyb139-159-150-152:~/gitcode$ git add .
hyb139-159-150-152:~/gitcode$ git commit -mmodify ReadMe for new features
[dev3 cd2f149] modify ReadMe for new features
1 file changed, 1 insertion()
# 此时新功能叫停
# 切回master准备删除dev3
hyb139-159-150-152:~/gitcode$ git checkout master
Switched to branch master
# 常规删除dev3分支时失败
hyb139-159-150-152:~/gitcode$ git branch -d dev3
error: The branch dev3 is not fully merged.
If you are sure you want to delete it, run git branch -D dev3.直接使用传统的删除分支的方法不行按照提示有了如下方式:
hyb139-159-150-152:~/gitcode$ git branch -D dev3
Deleted branch dev3 (was cd2f149).
hyb139-159-150-152:~/gitcode$ git branch
* master 7.5小结
分支在实际中有什么用呢假设你准备开发一个新功能但是需要两周才能完成第一周你写了50%的代码如果立刻提交由于代码还没写完不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交又存在丢失每天进度的巨大风险。现在有了分支就不用怕了。你创建了一个属于你自己的分支别人看不到还继续在原来的分支上正常工作而你在自己的分支上干活想提交就提交直到开发完毕后再一次性合并到原来的分支上这样既安全又不影响别人工作。并且 Git 无论创建、切换和删除分支Git在1秒钟之内就能完成无论你的版本库是1个文件还是1万个文件。 八、远程操作
8.1理解分布式版本控制系统
我们目前所说的所有内容工作区暂存区版本库等等都是在本地也就是在你的笔记本或者计算机上。而我们的 Git 其实是分布式版本控制系统什么意思呢可以简单理解为我们每个人的电脑上都是一个完整的版本库这样你工作的时候就不需要联网了因为版本库就在你自己的电脑上。既然每个人电脑上都有一个完整的版本库那多个人如何协作呢比方说你在自己电脑上改了文件A你的同事也在他的电脑上改了文件A这时你们俩之间只需把各自的修改推送给对方就可以互相看到对方的修改了。 分布式版本控制系统的安全性要高很多因为每个人电脑里都有完整的版本库某一个人的电脑坏掉了不要紧随便从其他人那里复制一个就可以了。 在实际使用分布式版本控制系统的时候其实很少在两人之间的电脑上推送版本库的修改因为可能你们俩不在一个局域网内两台电脑互相访问不了。也可能今天你的同事病了他的电脑压根没有开机。因此分布式版本控制系统通常也有一台充当“中央服务器”的电脑但这个服务器的作用仅仅是用来方便“交换”大家的修改没有它大家也一样干活只是交换修改不方便而已。有了这个“中央服务器”的电脑这样就不怕本地出现什么故障了比如运气差硬盘坏了上面的所有东西全部丢失包括git的所有内容 九、远程仓库 Git 是分布式版本控制系统同一个 Git 仓库可以分布到不同的机器上。怎么分布呢最早肯定只有一台机器有一个原始版本库此后别的机器可以 “克隆” 这个原始版本库而且每台机器的版本库其实都是一样的并没有主次之分。你肯定会想至少需要两台机器才能玩远程库不是但是我只有一台电脑怎么玩其实一台电脑上也是可以克隆多个版本库的只要不在同一个目录下。不过现实生活中是不会有人这么傻的在一台电脑上搞几个远程库玩因为一台电脑上搞几个远程库完全没有意义而且硬盘挂了会导致所有库都挂掉所以我也不告诉你在一台电脑上怎么克隆多个仓库。实际情况往往是这样找一台电脑充当服务器的角色每天24小时开机其他每个人都从这个“服务器”仓库克隆一份到自己的电脑上并且各自把各自的提交推送到服务器仓库里也从服务器仓库中拉取别人的提交。完全可以自己搭建一台运行 Git 的服务器不过现阶段为了学 Git 先搭个服务器绝对是小题大作。好在这个世界上有个叫 GitHub 的神奇的网站从名字就可以看出这个网站就是提供 Git 仓库托管服务的所以只要注册一个GitHub账号就可以免费获得 Git 远程仓库。 9.1新建远程仓库 9.2克隆远程仓库
克隆/下载远端仓库到本地需要使用 git clone 命令后面跟上我们的远端仓库的链接远端仓库 的链接可以从仓库中找到选择“克隆/下载”获取远程仓库链接 SH 协议和 HTTPS 协议是 Git 最常使用的两种数据传输协议。SSH 协议使用了公钥加密和公钥登陆机制体现了其实用性和安全性使用此协议需要将我们的公钥放上服务器由 Git 服务器进行管理。使用 HTTPS 方式时没有要求可以直接克隆下来。 使用 HTTPS 方式 hyb139-159-150-152:~$ git clone https://gitee.com/hyb91/git_teaching.git
Cloning into git_teaching...
Username for https://gitee.com: hyb91
Password for https://hyb91gitee.com:
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (4/4), 1.80 KiB | 1.80 MiB/s, done.
hyb139-159-150-152:~$ ls
gitcode git_teaching
hyb139-159-150-152:~$ ls git_teaching/
README.en.md README.md 使用 SSH 方式 hyb139-159-150-152:~$ git clone gitgitee.com:hyb91/git_teaching.git
Cloning into git_teaching...
The authenticity of host gitee.com (212.64.63.215) cant be established.
ECDSA key fingerprint is SHA256:FQGC9Kn/eye1W8icdBgrQpKkGYoFgbVr17bmjey0Wc.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added gitee.com,212.64.63.215 (ECDSA) to the list of know
gitgitee.com: Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists. 使用 SSH 方式克隆仓库由于我们没有添加公钥到远端库中服务器拒绝了我们的 clone 链接。需要我们设置一下
第一步创建SSH Key。在用户主目录下看看有没有.ssh目录如果有再看看这个目录下有没有id_rsa 和id_rsa.pub 这两个文件如果已经有了可直接跳到下一步。如果没有需要创建 SSH Key
# 注意要输入自己的邮箱然后一路回车使用默认值即可
hyb139-159-150-152:~$ ssh-keygen -t rsa -C 2689241679qq.com
Generating public/private rsa key pair.
Enter file in which to save the key (/home/hyb/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/hyb/.ssh/id_rsa
Your public key has been saved in /home/hyb/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:sepKZUwKIXjJxYcot49tvOWAapEhdsRqVDFSmgQZo 2689241679qq.com
The keys randomart image is:
---[RSA 3072]----
|*oB |
|Oo . |
|E*o .. . |
| *o o |
| o *o S |
|. o .. |
| o .. |
|. .... |
| ...o. |
----[SHA256]-----
顺利的话可以在用户主目录里找到.ssh 目录里面有id_rsa 和id_rsa.pub 两个文件这两 个就是SSH Key的秘钥对 id_rsa 是私钥不能泄露出去 id_rsa.pub 是公钥可以放心地告 诉任何人。
hyb139-159-150-152:~$ ls -a .ssh/
. .. id_rsa id_rsa.pub known_hosts
第二步添加自己的公钥到远端仓库。 点击确认后需要对你进行认证输入你的账号密码即可。至此我们的准备工作全部做完欢快的clone吧。
hyb139-159-150-152:~$ git clone gitgitee.com:hyb91/git_teaching.git
Cloning into git_teaching...
Warning: Permanently added the ECDSA host key for IP address 212.64.63.190 to
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (4/4), done.
hyb139-159-150-152:~$ ls
gitcode git_teaching
hyb139-159-150-152:~$ ls git_teaching/
README.en.md README.md
done, 成功如果有多个人协作开发GitHub/Gitee 允许添加多个公钥只要把每个人的电脑上的 Key 都添加到 GitHub/Gitee就可以在每台电脑上往 GitHub/Gitee 上提交推送了。 当我们从远程仓库克隆后实际上 Git 会自动把本地的 master 分支和远程的 master 分支对应起来并且远程仓库的默认名称是 origin 。在本地我们可以使用 git remote 命令来查看远程库的 信息如
hyb139-159-150-152:~/git_teaching$ git remote
origin
或者用 git remote -v 显示更详细的信息
hyb139-159-150-152:~/git_teaching$ git remote -v
origin gitgitee.com:hyb91/git_teaching.git (fetch)
origin gitgitee.com:hyb91/git_teaching.git (push)
上面显示了可以抓取和推送的origin的地址。如果没有推送权限就看不到 push 的地址。
9.3向远程仓库推送
本地已经clone 成功远程仓库后我们便可以向仓库中提交内容例如新增一个file.txt 文件
# 新建文件
hyb139-159-150-152:~/git_teaching$ ls
README.en.md README.md
hyb139-159-150-152:~/git_teaching$ vim file.txt
hyb139-159-150-152:~/git_teaching$ cat file.txt
hello git
# 提交文件
hyb139-159-150-152:~/git_teaching$ git add .
hyb139-159-150-152:~/git_teaching$ git commit -mcreate file.txt
[master 7ce3183] create file.txt
1 file changed, 1 insertion()
create mode 100644 file.txt
提交时要注意如果我们之前设置过全局的 name 和 e-mail这两项配置需要和 gitee 上配置的用户名和邮箱一致否则会出错。 或者从来没有设置过全局的 name 和 e-mail那么我们第一次提交时也会报错。这就需要我们重新配置下了同样要注意需要和 gitee 上配置的用户名和邮箱一致。如何配置已讲过在这里就不再赘述。到这里我们已经将内容提交至本地仓库中如何将本地仓库的内容推送至远程仓库呢需要使用 git push 命令该命令用于将本地的分支版本上传到远程并合并命令格式如下
git push 远程主机名 本地分支名:远程分支名
# 如果本地分支名与远程分支名相同则可以省略冒号
git push 远程主机名 本地分支名 此时我们要将本地的 master 分支推送到 origin 主机的 master 分支则可以
hyb139-159-150-152:~/git_teaching$ git push origin master
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 308 bytes | 308.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.4]
To gitee.com:hyb91/git_teaching.git
c6ce3f0..7ce3183 master - master
推送成功这里由于我们使用的是 SSH 协议是不用每一次推送都输入密码的方便了我们的推送操作。如果你使用的是 HTTPS 协议有个麻烦地方就是每次推送都必须输入口令。
接下来看看码云远端
代码已经被推送至远端了 9.4拉取远程仓库 在 gitee 上点击 README.md 文件并在线修改它: 此时远程仓库是要领先于本地仓库一个版本为了使本地仓库保持最新的版本我们需要拉取下远端代码并合并到本地。Git 提供了git pull 命令该命令用于从远程获取代码并合并本地的版 本。格式如下
git pull 远程主机名 远程分支名:本地分支名
# 如果远程分支是与当前分支合并则冒号后面的部分可以省略。
git pull 远程主机名 远程分支名 # 拉取远程分支并与当前分支进行合并
hyb139-159-150-152:~/git_teaching$ git pull origin master
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 1.02 KiB | 1.02 MiB/s, done.
From gitee.com:hyb91/git_teaching
* branch master - FETCH_HEAD
7ce3183..60e6b0a master - origin/master
Updating 7ce3183..60e6b0a
Fast-forward
README.md | 2
1 file changed, 2 insertions()
hyb139-159-150-152:~/git_teaching$ cat README.md
...
第一次修改内容
我们发现拉取成功了 十、配置 Git
10.1忽略特殊文件
在日常开发中我们有些文件不想或者不应该提交到远端比如保存了数据库密码的配置文件那怎么让 Git 知道呢在 Git 工作区的根目录下创建一个特殊的.gitignore 文件然后把要忽略的文件 名填进去Git 就会自动忽略这些文件了。不需要从头写.gitignore 文件gitee 在创建仓库时就可以为我们生成不过需要我们主动勾选一下 如果当时没有选择这个选择在工作区创建一个也是可以的。无论哪种方式最终都可以得到一个完整的.gitignore 文件例如我们想忽略以 .so 和 .ini 结尾所有文件 .gitignore 的内容 如下
# 省略选择模本的内容
...
# My configurations:
*.ini
*.so
在.gitignore 文件中也可以指定某个确定的文件。 最后一步就是把.gitignore 也提交到远端就完成了
hyb139-159-150-152:~/git_teaching$ vim .gitignore
hyb139-159-150-152:~/git_teaching$ git add .
hyb139-159-150-152:~/git_teaching$ git commit -madd .gitignore
[master 97811ab] add .gitignore
1 file changed, 3 insertions()
create mode 100644 .gitignore
hyb139-159-150-152:~/git_teaching$ git push origin master
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 362 bytes | 362.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.4]
To gitee.com:hyb91/git_teaching.git
60e6b0a..97811ab master - master
接着我们就来验证一下.gitignore文件的能力在工作区新增两个文件 a.so b.ini :
hyb139-159-150-152:~/git_teaching$ touch a.so b.ini
hyb139-159-150-152:~/git_teaching$ git status
On branch master
Your branch is up to date with origin/master.
nothing to commit, working tree clean
检验.gitignore 的标准就是git status 命令是不是说working tree clean 。我们发现 Git 并没有提示在工作区中有文件新增果然.gitignore 生效了 但有些时候你就是想添加一个文件到 Git但由于这个文件被.gitignore 忽略了根本添加不 了那么可以用 -f 强制添加 $ git 1 add -f [filename]
或者你发现可能是.gitignore 写得有问题需要找出来到底哪个规则写错了比如说 a.so 文件 是要被添加的可以用 git check-ignore 命令检查
hyb139-159-150-152:~/git_teaching$ git check-ignore -v a.so
.gitignore:3:*.so a.so
Git 会告诉我们 .gitignore 的第3行规则忽略了该文件于是我们就可以知道应该修订哪个规 则。还有些时候当我们编写了规则排除了部分文件时例如
# 排除所有.开头的隐藏文件:
.*
但是我们发现.* 这个规则把.gitignore 也排除了。虽然可以用 git add -f 强制添加进去但有强迫症的童鞋还是希望不要破坏.gitignore 规则这个时候可以添加一条例外规则
# 排除所有.开头的隐藏文件:
.*
# 不排除.gitignore
!.gitignore
把指定文件排除在.gitignore 规则外的写法就是! 文件名所以只需把例外文件添加进去即 可。
10.2给命令配置别名
在我们使用 Git 期间有些命令敲的时候着实让人头疼太长了。。幸运的是git支持对命令进行简化
举个例子将git status 简化为git st 对应的命令为
$ git config --global 1 alias.st status
--global 参数是全局参数也就是这些命令在这台电脑的所有Git仓库下都有用。如果不加那只 针对当前的仓库起作用。好了现在敲git st 看看效果
hyb139-159-150-152:~/git_teaching$ git st
On branch master
Your branch is up to date with origin/master.
nothing to commit, working tree clean
再来配置一个git last 让其显示最后一次提交信息
$ git config --global alias.last log -1
这样用 git last 就能显示最近一次的提交
hyb139-159-150-152:~/git_teaching$ git last
commit 97811abd1d43774aeb54fee32bf4fc76b2b08170 (HEAD - master, origin/master,
Author: hyb91 2689241679qq.com
Date: Fri May 12 17:27:06 2023 0800
add .gitignore
不过我个人还是不推荐大家现在去使用他等大家工作了再去简化自己的工作吧. 十一、标签管理
11.1理解标签
标签tag 可以简单的理解为是对某次 commit 的一个标识相当于起了一个别名。例如在项目 发布某个版本的时候针对最后一次 commit 起一个 v1.0 这样的标签来标识里程碑的意义。这有什么用呢相较于难以记住的commit id tag 很好的解决这个问题因为tag 一定要给一个让人容易记住且有意义的名字。当我们需要回退到某个重要版本时直接使用标签就能很快定位到。
11.2创建标签
在Git中打标签非常简单首先切换到需要打标签的分支上
hyb139-159-150-152:~/git_teaching$ git branch
* master
然后敲命令git tag [name] 就可以打一个新标签
hyb139-159-150-152:~/git_teaching$ 1 git tag v1.0
可以用命令git tag 查看所有标签
hyb139-159-150-152:~/git_teaching$ git tag
v1.0
默认标签是打在最新提交的commit 上的。那如何在指定的commit上打标签呢方法是找到历史提 交的commit id然后打上就可以了示例如下
# 历史记录
hyb139-159-150-152:~/git_teaching$ git log --prettyoneline --abbrev-commit
97811ab (HEAD - master, tag: v1.0, origin/master, origin/HEAD) add .gitignore
60e6b0a update README.md.
7ce3183 create file.txt
c6ce3f0 Initial commit
# 对 Initial commit 这次提交打标签
hyb139-159-150-152:~/git_teaching$ git tag v0.9 c6ce3f0
hyb139-159-150-152:~/git_teaching$ git tag
v0.9
v1.0
注意标签不是按时间顺序列出而是按字母排序的。可以用 git show [tagname] 查看标签信息。
hyb139-159-150-152:~/git_teaching$ git show v1.0
commit 97811abd1d43774aeb54fee32bf4fc76b2b08170 (HEAD - master, tag: v1.0, orig
Author: hyb91 2689241679qq.com
Date: Fri May 12 17:27:06 2023 0800
add .gitignore
diff --git a/.gitignore b/.gitignore
...
Git 还提供可以创建带有说明的标签用-a指定标签名-m指定说明文字格式为
git tag -a [name] -1 m XXX [commit_id]
另外打完标签之后使用 tree .git 命令查看一下你的本地库有什么变化肯定能帮助你理解
11.3操作标签
如果标签打错了也可以删除
hyb139-159-150-152:~/git_teaching$ git tag
v0.9
v1.0
hyb139-159-150-152:~/git_teaching$ git tag -d v0.9
Deleted tag v0.9 (was c6ce3f0)
hyb139-159-150-152:~/git_teaching$ git tag
v1.0
因为创建的标签都只存储在本地不会自动推送到远程。所以打错的标签可以在本地安全删除。 如果要推送某个标签到远程使用命令git push origin tagname
hyb139-159-150-152:~/git_teaching$ git tag
v1.0
hyb139-159-150-152:~/git_teaching$ git push origin v1.0
Total 0 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.4]
To gitee.com:hyb91/git_teaching.git
* [new tag] v1.0 - v1.0
此时查看远端码云看到了标签已经被更新完美
当然如果你本地有很多标签也可以一次性的全部推送到远端:
git 1 push origin --tags 如果标签已经推送到远程要删除远程标签就麻烦一点先从本地删除
hyb139-159-150-152:~/git_teaching$ git tag
v1.0
hyb139-159-150-152:~/git_teaching$ git tag -d v1.0
Deleted tag v1.0 (was 97811ab)
然后从远程删除。删除命令也是push但是格式如下
hyb139-159-150-152:~/git_teaching$ git push origin :refs/tags/v1.0
remote: Powered by GITEE.COM [GNK-6.4]
To gitee.com:hyb91/git_teaching.git
- [deleted] v1.0
在码云上查看确实删除成功