首页 > 自考资讯 > 高考百科

深入浅出 Git(深入浅出 公文)

小条 2024-10-22

git 初体验

在使用git之前,您必须设置用户名和电子邮件以识别作者。此信息将出现在您的提交记录中。

git config --global user.name 'Ye Hanlin' git config --global user.email 'yehanlin@scratchlab.com' 此信息以以下格式出现在提交记录中:

commit 270d71a66ec534ea4d567132b8d1ff9eb857a399Author: Ye Hanlin yehanlin@scratchlab.comDate: Sat Nov 6 16:18:17 2021 +0800在Alphabet.txt 中添加a 以下步骤演示了使用git 的过程。

1.创建Proja存储库

mkdir githubgit init --bare github/proja.git2 模拟两个用户进行开发,每个用户从存储库克隆proja 版本的库。

mkdir user1cd user1git克隆/home/yehanlin/github/proja.gitmkdir user2cd user2git克隆/home/yehanlin/github/proja.git/3。 user1 创建num.txt 并向该文件写入1。

回显1 num.txt4。 user1将num.txt添加到暂存区进行提交。

git add num.txt5。 user1 发送num.txt。

git commit -m "user add 1 in num.txt" 6. 重复步骤3、4 和5 创建Alphabet.txt 和color.txt。

echo aalphabet.txtgit addalphabet.txtgit commit -m “user1在alphabet.txt中添加a” echo red color.txtgit add color.txtgit commit -m “user1在color.txt中添加红色” 7. user1推送

git Push8 撤回提交。

使用git pull9 查看提交日志。

git logcommit 700e481d0f58aafe01c92583dfd31b5e5cfe47a6 (HEAD - Master, Origin/Master)Author: Ye Hanlin yehanlin@scratchlab.comDate: Sun Nov 14 17:02:40 2021 +0800user1 红色添加。提交a99c124d0bef020f14adf0c94c2ca9376f60a1f6Author:叶汉林yehanlin@scratchlab.comDate:周日11月14日17:02:21 2021 +0800user1添加alphabet.txtcommit 1d7925b777604 f73 d4227249e2aad68b9d6bb774Author: Ye Hanlin yehanlin@scratchlab.comDate: Sun Nov 14 17:01:50 2021 +0800user1 num.tx 加1 集中版本控制,例如vs 或svn与System 相比,使用git 存在一些差异。

Git引入了暂存区,你只能发送添加到暂存区的内容。如果用户做了很多修改,需要分批提交(比如用户修复了5个bug,需要分5批提交),则需要提交的内容可以暂时添加到自己的存储中空间。和svn的add命令类似,批量运行然后发送。 git 是一个分布式版本控制系统。当用户提交时,提交内容将进入本地存储库,并在其他用户可见之前推送到远程存储库。 Git 鼓励用户频繁提交以保存历史记录。减少推送以避免影响其他用户(例如,用户可能会频繁提交并在完成后推送)。如果使用svn等集中式版本控制系统,频繁的提交会导致冲突。

工作区

检查user1目录下proja的配置。 以下是命令和结果:

tree -a -L 1 proja/proja/ Alphabet.txt color.txt .git num.txt proja目录成为工作空间,用户操作的目录和文件为proja/.git位于这个目录中,是暂存区和本地版本库。

工作区是文件系统中进行开发的目录树。

Tree proja/proja/什么时候表示alphabet.txt color.txt num.txt

版本库

.git 目录是临时存储区和版本库。 git 存储库类似于单链表,如下所示。

72bf6b27610e46029ff7311af2cc9dc4~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1730157593&x-signature=YGhO3EfqKwq6npAaMcJHJjEm5%2Bg%3D使用git log命令查看链表。

git log --graph --pretty=raw* 提交700e481d0f58aafe01c92583dfd31b5e5cfe47a6 | 树d7be21b272e8793bf891ed72d57ac8898844993b | 作者叶汉林yehanlin@scratchlab.com 16368805 60 +08 00|提交者叶瀚林yehanlin@scratchlab.com 1636880560 +0800|| 为user1 添加红色。 txt|* 提交a99c124d0bef020f14adf0c94c2ca9376f60a1f6| 作者叶瀚林yehanlin@scratchlab.com 1636880541 +0800| 提交者叶瀚林yehanlin@scratchlab.com 1636880541 +0800|| a 到Alphabet.txt 添加|* 提交1 d7925b777604f73d4227249e2aad68b9d6bb774 树96f36c5a16702b8314e9b2d9c89406b12d7a0930作者叶汉林yehanlin@Scratchlab com。 1636880510 +0800committer 叶瀚林yehanlin@scratchlab.com 1636880510 +0800user1 在num.txt中加1 图中,提交、目录树、文件都是以对象的形式存在,可以理解为内存中的对象。 通过序列化数据结构生成的文件。 Git 有四种类型的对象:commit、tree、blob 和tag,其中blob 用于存储文件。对象由根据其内容、时间戳、作者等计算的哈希值唯一标识。与文件的md5 值类似,该哈希值称为对象ID。使用git cat-file 命令查看对象。

git cat-file -t object id # 显示对象类型git cat-file -p object id # 显示对象内容链表中的每个节点代表一个提交对象。该对象包含作者信息、提交时间、提交描述、父级提交和目录树信息。

git cat-文件-p 700e481d0f58aafe01c92583dfd31b5e5cfe47a6tree d7be21b272e8793bf891ed72d57ac8898844993bparent a99c124d0bef020f14adf0c94c2ca9376f60a1f6作者叶瀚林yehanlin@scratchlab.com 1636880560 +0800committer 叶瀚林yehanlin@scratchlab.com 1636880560 +0800user1 在color.txtdirectory tree 中添加red 记录目录树对应的目录树一个树对象。提交快照。 Git只考虑文件数据的全局变化(大多数版本控制系统只考虑文件内容的特定差异)。这意味着每次提交文件时,Git 都会记录完整的目录树。

git cat-file -p d7be21b272e8793bf891ed72d57ac8898844993b100644 blob 78981922613b2afb6025042ff6bd878ac1994e85 Alphabet.txt100644 blob a9d1386a1d99728de0 1 0 ad4044fb984886b57f33 color.txt100644 blob d00491fd7e5bb6fa28c517a0bb32b8b506539d4d num.txt 目录树中的文件以BLOB 对象的形式存储。包含BLOB ID、文件名、权限和其他信息的目录树。

git cat-file -p a9d1386a1d99728de010ad4044fb984886b57f33redgit 保存完整的对象(经过压缩优化)而不是增量。这称为松散物体。例如,当您第一次发送num.txt 时,内容将如下所示:

1 第二次提交的内容如下:

发送122 次的目录树会保存num.txt 的完整内容,而不是第二次发送,后者仅保存您可能期望的差异。

2 这会浪费磁盘空间,但速度非常快。 Git 提供了多个存储库管理命令,您可以自行运行这些命令来优化和清理这些对象。

git commit操作相当于头插入。

暂存区

临时存储类似于树对象,是目录树对象。树对象是只读的,创建后无法修改。暂存区和树对象有非常不同的实现,因为暂存区需要频繁地读写,而这正是git 的设计目的。

使用git ls-files 查看暂存区。

git ls-filesalphabet.txtcolor.txtnum.txtgit ls-files 有以下选项:

-c:显示暂存区中的文件(默认) -d:显示暂存区中但已从工作区中删除的文件-m:显示暂存区中但已从工作区中删除或移除的文件工作区显示修改的文件-s:显示暂存区中的对象信息。使用git add 将文件添加到暂存区。

echo big size.txtgit add size.txtgit ls-filesalphabet.txtcolor.txtnum.txtsize.txt 使用git rm 从工作区和暂存区域中删除文件。

git rm num.txt 使用gitrestor --staged 撤消暂存区域中的更改(添加、删除、更改)。

echo Rabbit Animal.txtgit add Anime.txtgitrestor --staged Animal.txt # 恢复添加到暂存区的文件git rm color.txtgit Restore --staged color.txt # 根据添加到暂存区的删除内容return echo 2 num 。 txtgit add num.txtgitrestor --staged num.txt # 要撤消对暂存区域所做的更改,请使用git list 使用暂存区域进行更改(删除、更改)。

rm color.txtgit list color.txt # 撤消对工作区中文件的删除echo 2 num.txtgit list num.txt # 撤消对工作区的更改将文件添加或修改到临时存储生成BLOB 对象。这些BLOB 对象将被永久保存,并记录文件的全部内容。因此,Git有一个超时机制,定期清理未引用的对象,并在暂存区生成大量临时对象。

git diff

Git 在您的工作区、暂存区域和版本库中存储版本库的副本。运行以下命令时,三个副本是不同的:

echo audi car.txtgit add car.txtecho byd car.txt 使用git diff --staged 查看版本库和暂存区的差异。

git diff --stageddiff --git a/car.txt b/car.txt 新文件模式100644index 0000000.51a0cb3--- /dev/null+++ b/car.txt@@ -0,0 +1 @@+audi使用git diff 查看暂存区和工作区之间的差异。

git diffdiff --git a/car.txt b/car.txtindex 51a0cb3.9b74cca 100644--- a/car.txt+++ b/car.txt@@ -1 +1,2 @@audi+byd

分支

in在存储库图中,您可以为表头指定一个名称(例如dev、stable 等),并使用该名称来引用发送链。这个名字就叫分支。在git中,分支以文本文件的形式存在。文件名是分支名,文件内容是最新的提交ID。当执行提交时,该文件的内容会自动更新为最新的提交ID。

在git 中,分支文件位于.git/refs/heads 目录中。

Tree .git/refs/heads/.git/refs/heads/ mastercat .git/refs/heads/master700e481d0f58aafe01c92583dfd31b5e5cfe47a6 # 最新提交ID使用git分支来管理分支。

操作

命令

解释

创造

git 分支分支名称提交ID

根据提交创建分支

擦除

gitbranch -d 分支名称

删除分支

查看

git分支

查看您当地的分行

根据上次提交创建一个开发分支(使用git 日志可见)。

git 分支dev a99c124d0bef020f14adf0c94c2ca9376f60a1f6git 分支dev* 主树.git/refs/heads/.git/refs/heads/til dev mastercat .git/refs/heads/deva99c124d0bef020f14adf0c94c2ca9376 f 6 0a1f6 使用git 分支显示分支然后* before master 表示当前分支(仓库中有很多分支,使用的是当前分支)。在git中,当前分支由.git/HEAD表示。该文件是一个文本文件,其内容是分支名称。

使用cat .git/HEADref: refs/heads/master git 开关切换分支。 命令的格式为:

git switch Branchname 切换分支的本质是改变HEAD的内容。 HEAD 的内容可以是分支的名称或特定的提交ID。如果要切换到提交ID,则必须指定-d 选项。

git switch -d d8b8607a4e5ea9cfacf90bef08714f2e0745697f 目前HEAD处于分离头指针状态,无法发送。

接下来,切换到dev分支。

git 远程rm 仓库名称

删除远程存储库

修订

git 远程设置url reponame repopath

git 远程rname reponame reponame_new

更改远程存储库

查看

git 远程-v

显示远程存储库

创建两个新存储库。

mkdir gitlabgit init --bare gitlab/proja.gitmkdir giteemkdir gitee --bare/proja.git 向user1 添加两个远程存储库。

git 远程添加gitlab /home/yehanlin/gitlab/proja.git 远程添加gitee /home/yehanlin/gitee/proja.gitgit 远程-vgitee /home/yehanlin/gitee/proja.git (fetch)gitee /home/yehanlin/gitee /proja.git (推)gitlab /home/yehanlin/gitlab/proja.git (获取)gitlab /home/yehanlin/gitlab/proja.git (推)origin /home/yehanlin/github/proja.git/(获取)来源/home/yehanlin/github/proja.git/(push) 每个远程存储库对应于.git/config 文件的远程部分。 user1的初始版本库是从github/proja.git克隆的,版本库自动命名为origin。

[远程'origin']url=/home/yehanlin/github/proja.git/fetch=+refs/heads/*:refs/remotes/origin/*[远程'gitlab']url=/home/yehanlin/gitlab/proja .gitfetch=+refs/heads/*:refs/remotes/gitlab/*[remote 'gitee']url=/home/yehanlin/gitee/proja.gitfetch=+refs/heads/*:refs/remotes/gitee/*通常是远程存储库URL 既是拉取URL,又是推送URL。您可以为推送设置单独的URL(不能为拉取指定单独的URL)。

git Remote set-url --push gitee /home/yehanlin/github/proja.git 远程-vgitee /home/yehanlin/gitee/proja.git (fetch)gitee /home/yehanlin/github/proja.git (push)。设置pull和push两个URL通常适合以下情况: 项目有官方库,有核心人员

员维护。当用户想为该项目贡献代码时,首先克隆一个自己专属的副本库。用户从官方库pull代码;向副本库push代码,然后通过pull requst的方式向官方库提交代码。 remote的fetch参数是一个引用表达式,对于gitlab来说,表示远程版本库gitlab中的分支拷贝到本地版本库的.git/refs/remotes/gitlab/目录下,分支名字不变。这种关系是可配置的,但通常不会有人自找麻烦去修改fetch参数。

git push

使用git push向远程版本库推送数据,命令格式如下: git push <reponame> <branchname>branchname是一个引用表达式,可以实现将本地x分支推送到远程y分支的功能。但通常是同名分支推送,因此,该引用表达式可简化为分支名。 在本地版本库创建dev分支,并推送到gitlab远程版本库: git branch devgit push gitlab devgitlab远程版本库本来没有任何分支,通过git push的方式在gitlab远程版本库创建了dev分支: cd /home/yehanlin/gitlab/proja.gitgit branchdev使用-d选项可删除远程版本库中的分支: git push gitlab -d devTo /home/yehanlin/gitlab/proja.git- [deleted] dev

git pull

使用git pull从远程版本库获取数据,获取的数据包括对象、分支等。pull由两个步骤组成: git pull = git fetch + git mergefetch是指从远程版本库获取数据;merge是指将从远程版本库合并到的本地版本库。 切换到dev分支,然后执行git pull,我们预期从gitlab远程版本库获取数据: git switch devgit pullThere is no tracking information for the current branch.Please specify which branch you want to merge with.See git-pull(1) for details.git pull <remote> <branch>If you wish to set tracking information for this branch you can do so with:git branch --set-upstream-to=<remote>/<branch> dev结果,pull失败,提示用户缺少分支跟踪。 分支追踪是指本地版本库的某个分支与哪个远程版本库的哪个分支是关联的。使用git push在远程版本库创建分支时,并没有创建分支追踪。 使用git branch命令管理分支追踪: 操作 命令 说明 设置 git branch -t <remotebranchname> <branchname> 设置分支跟踪 取消 git branch --unset-upstream <branchname> 取消分支追踪 查看 git branch -vv 查看分支追踪 设置本地dev分支追踪远程版本库gitlab的dev分支: git branch -u gitlab/dev devBranch 'dev' set up to track remote branch 'dev' from 'gitlab'.git branch -vv* dev a99c124 [gitlab/dev] user1 add a in alphabet.txtmaster 315c595 [origin/master] Merge branch 'master' of /home/yehanlin/github/proja每个分支跟踪对应.git/config中的一个branch小节: [remote "origin"]url = /home/yehanlin/github/proja.git/fetch = +refs/heads/*:refs/remotes/origin/*[branch "master"]remote = originmerge = refs/heads/master[remote "gitlab"]url = /home/yehanlin/gitlab/proja.gitfetch = +refs/heads/*:refs/remotes/gitlab/*[remote "gitee"]url = /home/yehanlin/gitee/proja.gitfetch = +refs/heads/*:refs/remotes/gitee/*[branch "dev"]remote = gitlabmerge = refs/heads/dev此时,执行git pull就可以成功了: git pullAlready up to date.执行pull时,根据当前分支dev在.git/config中查找分支跟踪,然后从remote参数指定的远程版本库中拉取数据,然后合并到merge参数指定的分支中。 用户可以指定本地版本库的x分支追踪远程版本库的y分支,但通常是同名分支追踪。 fetch是指从远程版本库下载对象和引用等,命令格式如下: git fetch <reponame>若没有指定远程版本库,根据当前分支的分支追踪确定远程版本库。 远程分支存储在./git/refs/remotes/<reponame>/目录下。使用git branch -r查看远程分支: git branch -rgitlab/devorigin/master执行git status时,会提示本地分支与远程分支的差距。此时,比较的就是本地分支与remotes下的分支,而非真正远程版本库中的分支。 git statusOn branch devYour branch is ahead of 'gitlab/dev' by 1 commit....git push时自动更新remotes下的引用,无需再次fetch: git pushEnumerating objects: 5, done....git statusOn branch devYour branch is up to date with 'gitlab/dev'....远程分支在remotes目录下,需要将远程分支与本地分支merge,用户才可使用。 merge操作合并的是两个分支。merge将commit对应的目录树和当前分支的目录树进行合并,合并后的提交以当前分支的提交作为第一个父提交,以commit为第二个父提交。 merge的本质是将两颗目录树及其中的文件合并,如果能自动合并则自动合并;如果不能自动合并,则将两个文件的内容合在一起,以冲突的形式标出,让用户自己决策保留哪些部分。理论上,任意两颗目录树均可合并。 git使用如下方式标识冲突: <<<<<<<内容1=======内容2>>>>>>>内容1为本地分支的内容;内容2为远程分支的内容。用户需解决冲突,然后提交,新提交有两个父提交。merge后会覆盖工作区与暂存区。 merge对工作区/暂存区的影响遵循保留修改的原则,即merge时,尽量保留用户当前修改。下表列出了执行merge时,几种典型的工作区/暂存区情况及执行结果: 情形 结果 新增了文件 merge成功,新文件保留在工作区/缓存区 从工作区删除了文件 merge成功,恢复被删除的文件 从工作区和暂存区删除了文件 merge失败,提示先提交再合并 修改了工作区中的文件 merge失败,提示先提交再合并 修改了工作区和暂存区中的文件 merge失败,提示先提交再合并 通常merge由pull自动调用,也可手动执行git merge操作,命令格式如下: git merge <commit1> <commit2> <commit3>...该命令将commit1、commit2、commit3对应的分支合并到当前分支,通常只需一个分支。 echo "3" >> num.txtgit add num.txtgit commit -m "user1 add 3 in num.text on dev"[dev 3e40d0d] user1 add in num.text on dev1 file changed, 1 insertion(+)git switch masterSwitched to branch 'master'Your branch is up to date with 'origin/master'.git merge devMerge made by the 'recursive' strategy.num.txt | 3 ++-1 file changed, 2 insertions(+), 1 deletion(-)

tag

tag也叫里程碑,本质是命名的提交。比如,某次提交后,用户将程序打包发布,可将此次提交命名为v1.0.0。 tag分为轻量级tag和普通tag。创建轻量级tag方法如下: git tag <tagname> <commit>创建tag v1.0.0: git tag v1.0.0 66beaeef0c40704284ba4bd9d93345a385a027a1轻量级tag是位于.git/refs/tags目录下的文件,文件名为tag的名字,内容为commit id。 tree .git/refs/tags.git/refs/tags└── v1.0.0cat .git/refs/tags/v1.0.066beaeef0c40704284ba4bd9d93345a385a027a1创建tag的方法如下: git tag -m <message> <tagname> <commit>创建tag v2.0.0: git tag -m "version 2.0.0" v2.0.0 bc61c1fb3fe88207877e1a699b2721a0ec5273e2创建tag时,会创建一个tag对象,该对象包含commit id、tag作者、时间、message等信息。然后在.git/refs/tags目录下创建一文件文件,文件名为tag的名字,内容为新建tag对象的id。 tree .git/refs/tags.git/refs/tags├── v1.0.0└── v2.0.0cat .git/refs/tags/v2.0.0bff3af08213eb11a1195e2faa3bd76d4b685c114git cat-file -t bff3af08213eb11a1195e2faa3bd76d4b685c114taggit cat-file -p bff3af08213eb11a1195e2faa3bd76d4b685c114object bc61c1fb3fe88207877e1a699b2721a0ec5273e2type committag v2.0.0tagger Ye Hanlin <yehanlin@scratchlab.com> 1636880560 +0800version 2.0.0使用git tag -d tagname可删除tag: git tag -d v1.0.0Deleted tag 'v1.0.0' (was 66beaee)使用git tag可查看tag: git tagv1.0.0v2.0.0执行git push时,默认不会将tag推送给远程版本库,需要显示推送。 git push <reponame> <tagname>执行git pull时,默认会获取tag。tag并没有像远程分支那样存放在.git/refs/remotes目录下,而是与本地tag一样直接放在了.git/refs/tags目录下。使用--no-tags选项,可避免获取tag。 若本地版本库和远程版本库均有名为x的tag,则pull时,会忽略远程版本库中的x tag。

对象管理

版本库长期运行后,会产生许多垃圾,例如: 暂存区产生的临时对象由于重置而丢弃的提交及相关对象由于对象全量储存而浪费的磁盘空间使用git gc命令可对版本库进行一系列优化,例如: 删除未被关联且过期的对象将松散对象打包,采用增量存储方式,降低版本库大小将分支、tag等文件打包成一个文件 觉得不错,就请您转发 版权声明:本文转载于网络,版权归作者所有,如果侵权,请联系本站编辑删除

猜你喜欢