【Git企业级开发实战指南②】分支管理、远程操作

开源 0

目录

  • 一、分支管理
    • 1.1理解分支
    • 1.2创建分支
    • 1.3切换分支
    • 1.4合并分支
    • 1.5删除分支
    • 1.6合并冲突
    • 1.7 分支管理策略
      • 1.7.1分支策略
    • 1.8bug分支
    • 1.9删除临时分支
  • 二、远程操作
    • 2.1理解分布式版本控制系统
    • 2.2 远程仓库
      • 2.2.1 新建远程仓库
      • 2.2.2 克隆远程仓库
      • 2.2.3向远端仓库推送
      • 2.2.4拉取远端仓库
    • 2.3配置Git
  • 2.4 命令配置别名
  • 🍀小结🍀

在这里插入图片描述
在这里插入图片描述

🎉博客主页:.小智

🎉欢迎关注:👍点赞🙌收藏✍️留言

🎉系列专栏:Git企业级开发教程

🎉代码仓库:小智的代码仓库


一、分支管理

1.1理解分支

想象你正在写一本书,这本书的每一页都代表着你项目的一个版本。在Git中,每当你创建一个分支,实际上就是在书中创建了一本副本,你可以在副本中进行任何修改,而主版本则保持原样。

假设你的书的主版本(分支)是master,表示当前的最终版本。现在,你需要写一个新的章节,但你不确定这个章节是否会被最终采纳。为了安全起见,你创建了一个名为feature-chapter的新分支。

feature-chapter分支上,你可以尽情地写你的新章节,而不用担心影响到主版本(master分支)。你可以随意增删改这个章节的内容,直到你满意为止。

如果你在写作过程中发现有一些错别字需要更正,你可以在feature-chapter分支上进行修改,而不会影响到master分支的内容。这就好比在新分支中进行修正,不影响到书的主体内容。

当你完成了新章节的写作,并且对其内容进行了完善,你可以将feature-chapter分支合并回master分支。这就好比将你的新写作整合到书的主体中,使得所有读者都可以看到你的最新内容。

最后,一旦新章节被整合到了master分支中,你可以删除feature-chapter分支,因为它的使命已经完成了。这就好比在完成编辑后将草稿丢弃或者存档,因为它的内容已经被整合到了正式版本中。

通过这个例子能够帮助理解Git中分支的概念:它允许你在不影响到主要项目版本的情况下进行并行开发和测试,确保你的修改在准备好之后再与主要项目整合。

  • 主分支(通常是master)是项目的主要时间线。
  • HEAD是指向当前所在分支的指针,它可以让你知道当前在哪个分支上工作。
    在这里插入图片描述每次提交,master都会向后移动一步、这样,不断随着我们的提交,master分支的线也越来越长,而HEAD只要一直指向master分支即可指向当前分支。

1.2创建分支

Git支持我们查看或创建别的分支,我们可以自己创建一个dev分支:

ubuntu@xiaozhi:~/Desktop/gitcode$ git branch		#查看当前本地所有分支* masterubuntu@xiaozhi:~/Desktop/gitcode$ git branch dev  	#创建新的分支 devubuntu@xiaozhi:~/Desktop/gitcode$ git branch   dev* master

创建好分支之后*表示当前HEAD指向的是master分支。

ubuntu@xiaozhi:~/Desktop/gitcode$ ls .git/refs/heads/dev  masterubuntu@xiaozhi:~/Desktop/gitcode$ cat .git/refs/heads/*5c846bddb4d0afc3372d2de7a0b03dd490457b765c846bddb4d0afc3372d2de7a0b03dd490457b76ubuntu@xiaozhi:~/Desktop/gitcode$ cat .git/HEAD ref: refs/heads/master

两个分支指向同一个修改,但是HEAD还是指向的master分支。
画图总结:
在这里插入图片描述

1.3切换分支

可以使用git checkout命令来切换当前分支

ubuntu@xiaozhi:~/Desktop/gitcode$ git checkout dev #切换到dev切换到分支 'dev'ubuntu@xiaozhi:~/Desktop/gitcode$ git branch  	   #查看当前分支* dev  masterubuntu@xiaozhi:~/Desktop/gitcode$ cat .git/HEAD   #查看HEAD指针指向ref: refs/heads/dev

在这里插入图片描述
在dev分支下提交一次修改,master分支不受影响:

ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1 I am file1!aaaaaaaaaaaaubuntu@xiaozhi:~/Desktop/gitcode$ echo "I am dev!" >> file1 #修改file1文件ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1 I am file1!aaaaaaaaaaaaI am dev!ubuntu@xiaozhi:~/Desktop/gitcode$ git add .					#添加到暂存区ubuntu@xiaozhi:~/Desktop/gitcode$ git commit -m "md file1"	#添加到本地版本库[dev 68054cc] md file1 1 file changed, 1 insertion(+)ubuntu@xiaozhi:~/Desktop/gitcode$ git checkout master 		#切换到master分支切换到分支 'master'ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1 				#查看file1文件并没改变I am file1!aaaaaaaaaaaa

查看两个分支的指向:

ubuntu@xiaozhi:~/Desktop/gitcode$ cat .git/refs/heads/dev 		#查看dev分支的最后一次提交68054cc7bda01f41ff5bec07c6fe2408196e607fubuntu@xiaozhi:~/Desktop/gitcode$ cat .git/refs/heads/master 	#查看master分支的最后一次提交5c846bddb4d0afc3372d2de7a0b03dd490457b76

可以看到两个分支指向已经不同。再来通过画图理解:
在这里插入图片描述
从上图可以看出,当我们切换回来master分支的时候,当然看不到dev的提交了。

1.4合并分支

为了能在master分支上看到最新的提交,就要将dev分支合并到master分支:

ubuntu@xiaozhi:~/Desktop/gitcode$ git branch 		#当前处于master分支  dev* masterubuntu@xiaozhi:~/Desktop/gitcode$ git merge dev 	#使用merge将dev合并到master分支更新 5c846bd..68054ccFast-forward file1 | 1 + 1 file changed, 1 insertion(+)ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1 		#dev下的提交更新到了master分支上I am file1!aaaaaaaaaaaaI am dev!

git merge 命令用于合并指定分分到当前分支。合并后,master就能看到dev分支提交的内容了。
在这里插入图片描述
Fast-forward 代表“快进模式”,也就是直接把 master 指向 dev 的当前提交,所以合并速度非常快。当然,也不是每次合并都能 Fast-forward,我们后面会讲其他方式的合并。

1.5删除分支

合并完成后,dev 分支对于我们来说就没用了,那么 dev 分支就可以被删除掉。注意,如果当前正处于某分支下,就不能删除当前分支。

ubuntu@xiaozhi:~/Desktop/gitcode$ git branch * dev  masterubuntu@xiaozhi:~/Desktop/gitcode$ git branch -d deverror: 无法删除检出于 '/home/ubuntu/Desktop/gitcode' 的分支 'dev'

但是可以在别的分支区删除

ubuntu@xiaozhi:~/Desktop/gitcode$ git checkout master 切换到分支 'master'ubuntu@xiaozhi:~/Desktop/gitcode$ git branch -d dev 已删除分支 dev(曾为 68054cc)。

在这里插入图片描述
因为创建、合并和删除分支非常快,所以Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在master 分支上工作效果是一样的,但过程更安全。

1.6合并冲突

当两个分支上的修改互相冲突时,就会发生合并冲突。这时需要手动解决冲突。
实例:我们将创建一个dev1分支,将dev1中的file1文件修改之后进行addcommit,然后切换到master分支,在修改master分支中file1的内容然后再addcommit
使用git checkout -b dev1指令可以创建并切换至dev1分支。

ubuntu@xiaozhi:~/Desktop/gitcode$ git checkout -b dev1		#创建dev1分支并切换至dev1分支切换到一个新分支 'dev1'ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1 I am file1!aaaaaaaaaaaaI am dev!ubuntu@xiaozhi:~/Desktop/gitcode$ echo "aaaaaa" >>file1 ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1 I am file1!aaaaaaaaaaaaI am dev!aaaaaaubuntu@xiaozhi:~/Desktop/gitcode$ git add . ubuntu@xiaozhi:~/Desktop/gitcode$ git commit -m "md file1:a.."[dev1 6a71790] add file1:a.. 1 file changed, 1 insertion(+)ubuntu@xiaozhi:~/Desktop/gitcode$ git checkout master 		#切换至master分支切换到分支 'master'ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1 I am file1!aaaaaaaaaaaaI am dev!ubuntu@xiaozhi:~/Desktop/gitcode$ echo "cccccccc" >>file1 ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1 I am file1!aaaaaaaaaaaaI am dev!ccccccccubuntu@xiaozhi:~/Desktop/gitcode$ git add .ubuntu@xiaozhi:~/Desktop/gitcode$ git commit -m "md file1: c..."[master 7070712] md file1: c... 1 file changed, 1 insertion(+)

此时master和dev1都有了各自新的提交:
在这里插入图片描述
此时我们去合并两个分支就会发生冲突:

ubuntu@xiaozhi:~/Desktop/gitcode$ git merge dev1自动合并 file1冲突(内容):合并冲突于 file1自动合并失败,修正冲突然后提交修正的结果。

用vim打开file1文件来看看里面的内容:
在这里插入图片描述
此时我们就需要手动去调整冲突的代码,并再次提交更正后的代码

ubuntu@xiaozhi:~/Desktop/gitcode$ vim file1 ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1 I am file1!aaaaaaaaaaaaI am dev!aaaaaaccccccccubuntu@xiaozhi:~/Desktop/gitcode$ git add .ubuntu@xiaozhi:~/Desktop/gitcode$ git commit -m "merge dev1"[master f7fe134] merge dev1ubuntu@xiaozhi:~/Desktop/gitcode$ git status 位于分支 master无文件要提交,干净的工作区

此时就解决完了冲突。
在这里插入图片描述
git log也可以查看到分支合并的情况:

ubuntu@xiaozhi:~/Desktop/gitcode$ git log --graph --pretty=oneline --abbrev-commit *   f7fe134 (HEAD -> master) merge dev1|/  | * 6a71790 (dev1) add file1:a..* | 7070712 md file1: c...|/  

合并完成之后就可以删除dev1分支了

ubuntu@xiaozhi:~/Desktop/gitcode$ git branch   dev1* masterubuntu@xiaozhi:~/Desktop/gitcode$ git branch -d dev1 已删除分支 dev1(曾为 6a71790)。

1.7 分支管理策略

通常合并分支时,如果可以,Git会采用Fast forward模式。
Fast forward模式合并之后:
在这里插入图片描述
在这种Fast forward模式下,删除分支之后,我们查看历史分支的时候,会丢失掉分支信息,看不出来最新的提交时merge进来的还是正常提交的。

当有冲突时,我们解决冲突之后就会再次进行一次addcommit这样就不是Fast forward模式了,这样当我们删除当时为了解决合并冲突创建的dev的分支时,查看历史分支信息,也可以看到master其实是由别的分支合并过来的。
在这里插入图片描述
在这里插入图片描述
当然Git也支持我们强制禁用Fast forward模式,那么就是在merge的时候生成一个新的commit,这样就可以通过历史分支信息查看到分支信息。

ubuntu@xiaozhi:~/Desktop/gitcode$ git checkout -b dev2   # 切换到一个新分支 'dev2'ubuntu@xiaozhi:~/Desktop/gitcode$ echo "a,b,c,d" >>file1 ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1 I am file1!aaaaaaaaaaaaI am dev!aaaaaacccccccca,b,c,dubuntu@xiaozhi:~/Desktop/gitcode$ git add .ubuntu@xiaozhi:~/Desktop/gitcode$ git commit -m "md file1"   # 修改 file1[dev2 143edf4] md file1 1 file changed, 1 insertion(+)ubuntu@xiaozhi:~/Desktop/gitcode$ git checkout master   # 切换到分支 'master'ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1 I am file1!aaaaaaaaaaaaI am dev!aaaaaaccccccccubuntu@xiaozhi:~/Desktop/gitcode$ git merge --no-ff -m "merge dev2 noff" dev2   # 合并 dev2 分支(禁用快进模式),并添加合并注释Merge made by the 'ort' strategy. file1 | 1 + 1 file changed, 1 insertion(+)ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1 I am file1!aaaaaaaaaaaaI am dev!aaaaaacccccccca,b,c,d

在这里插入图片描述
在这里插入图片描述

1.7.1分支策略

在实际开发中,我们应该按照几个基本原则进行分支管理:

首先,master 分支应该是非常稳定的,仅用来发布新版本,平时不能在上面工作;那么在哪里工作呢?工作都在 dev 分支上,也就是说,dev 分支是不稳定的,直到某个时候,比如 1.0 版本发布时,再将 de 分支合并到 master 上,然后在 master 分支发布 1.0 版本。

你和你的团队每个人都在 dev 分支上工作,每个人都有自己的分支,时不时地往dev 分支上合并就可以了。

1.8bug分支

当我们在dev2分支上开发了一半的时候,突然发现master上有bug,需要解决,此时我们就需要新创建一个分支来修复bug,但是我们dev2分支在工作区开发了一半了,还无法提交,此时我们就需要用到git 给我们提供的一个隐藏功能,先将dev2工作区中修改先隐藏起来,使用命令:git stash

ubuntu@xiaozhi:~/Desktop/gitcode$ git checkout dev2   # 切换到分支 'dev2'ubuntu@xiaozhi:~/Desktop/gitcode$ vim file1   # 编辑 file1 文件ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1   # 查看 file1 文件内容I am file1!aaaaaaaaaaaaI am dev!aaaaaacccccccca,b,c,dI am coding...ubuntu@xiaozhi:~/Desktop/gitcode$ git status   # 查看工作区状态位于分支 dev2尚未暂存以备提交的变更:  (使用 "git add <文件>..." 更新要提交的内容)  (使用 "git restore <文件>..." 丢弃工作区的改动)	修改:     file1修改尚未加入提交(使用 "git add" 和/或 "git commit -a")ubuntu@xiaozhi:~/Desktop/gitcode$ git stash   # 将当前修改暂存起来保存工作目录和索引状态 WIP on dev2: 143edf4 md file1ubuntu@xiaozhi:~/Desktop/gitcode$ git status   # 再次查看工作区状态,确认是干净的位于分支 dev2无文件要提交,干净的工作区ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1   # 再次查看 file1 文件内容,确认没有修改丢失I am file1!aaaaaaaaaaaaI am dev!aaaaaacccccccca,b,c,d

存储好dev2工作区之后再去切换到master分支,建立临时分支来修复bug:

ubuntu@xiaozhi:~/Desktop/gitcode$ git checkout master   # 切换到分支 'master'ubuntu@xiaozhi:~/Desktop/gitcode$ git checkout -b fix_bug   # 创建并切换到一个新分支 'fix_bug'ubuntu@xiaozhi:~/Desktop/gitcode$ vim file1   # 编辑 file1 文件,在末尾加了字母 'e'ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1   # 查看 file1 文件内容I am file1!aaaaaaaaaaaaI am dev!aaaaaacccccccca,b,c,d,eubuntu@xiaozhi:~/Desktop/gitcode$ git add .   # 将修改添加到暂存区ubuntu@xiaozhi:~/Desktop/gitcode$ git commit -m "fix bug"   # 提交修复 bug 的修改[fix_bug 15efd2f] fix bug 1 file changed, 1 insertion(+), 1 deletion(-)ubuntu@xiaozhi:~/Desktop/gitcode$ git checkout master   # 再次切换到分支 'master'ubuntu@xiaozhi:~/Desktop/gitcode$ git merge --no-ff -m "merge fix_bug branch" fix_bug   # 合并 fix_bug 分支到 master 分支(禁用快进模式),并添加合并注释Merge made by the 'ort' strategy. file1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1   # 查看合并后的 file1 文件内容I am file1!aaaaaaaaaaaaI am dev!aaaaaacccccccca,b,c,d,eubuntu@xiaozhi:~/Desktop/gitcode$ git branch -d fix_bug   # 删除已修复的 fix_bug 分支已删除分支 fix_bug(曾为 15efd2f)。

此时bug修复完成之后再来切换回dev2分支继续开发,此时的dev2工作区是干净的,我们可以使用git stash list查看暂存的内容。
可以使用git stash pop命令,恢复的同时也会把stash直接删除,恢复现场也可以采用 git stash apply 恢复,但是恢复后,stash 内容并不删除,你需要用 git stash drop 来删除;
可以多次 stash,恢复的时候,先用 git stash list 查看,然后恢复指定的 stash,用命令 git stash apply stash@{0}

ubuntu@xiaozhi:~/Desktop/gitcode$ git checkout dev2   # 切换到分支 'dev2'ubuntu@xiaozhi:~/Desktop/gitcode$ git status   # 查看工作区状态,确认干净位于分支 dev2无文件要提交,干净的工作区ubuntu@xiaozhi:~/Desktop/gitcode$ git stash list   # 查看当前的 stash 列表stash@{0}: WIP on dev2: 143edf4 md file1ubuntu@xiaozhi:~/Desktop/gitcode$ git stash pop   # 恢复最近的 stash,并删除该 stash位于分支 dev2尚未暂存以备提交的变更:  (使用 "git add <文件>..." 更新要提交的内容)  (使用 "git restore <文件>..." 丢弃工作区的改动)	修改:     file1修改尚未加入提交(使用 "git add" 和/或 "git commit -a")丢弃了 refs/stash@{0}(c6b089a96e51837881e27e98d98b6d6441b164c7)ubuntu@xiaozhi:~/Desktop/gitcode$ git stash list   # 再次查看 stash 列表,确认已删除ubuntu@xiaozhi:~/Desktop/gitcode$ vim file1   # 编辑 file1 文件ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1   # 查看 file1 文件内容I am file1!aaaaaaaaaaaaI am dev!aaaaaacccccccca,b,c,dI am coding...Doneubuntu@xiaozhi:~/Desktop/gitcode$ git add .   # 将修改添加到暂存区ubuntu@xiaozhi:~/Desktop/gitcode$ git commit -m "md file1"   # 提交修改,并添加提交注释[dev2 ee02a85] md file1 1 file changed, 1 insertion(+)

此时各个分支的状态图:
在这里插入图片描述
此时master分支上的代码是要领先建立dev2分支时的提交,所以dev2中看不到master中修复的bug。

我们的目标是将 dev2 分支合并到 master 分支,通常情况下,我们会切换到 master 分支并进行合并操作。然而,这样做存在一定风险。

合并分支时可能会发生代码冲突,需要手动解决这些冲突(通常在 master 分支上进行)。由于实际项目中可能涉及到大量代码,冲突解决过程可能并不简单,可能会涉及多行甚至数百行代码。在解决冲突的过程中,难免会出现手误或误解,导致错误的代码被错误地合并到 master 分支中。
在这里插入图片描述
解决这个问题的一个好的建议是:最好先在自己的分支(比如 dev2 分支)上合并 master 分支,然后再让 master 分支去合并 dev2 分支。这样做的目的是,如果在合并过程中出现冲突,可以在本地分支上解决并进行测试,而不会影响到 master 分支的稳定性和代码质量。
在这里插入图片描述

ubuntu@xiaozhi:~/Desktop/gitcode$ git branch    # 查看当前分支状态* dev2  masterubuntu@xiaozhi:~/Desktop/gitcode$ git merge master    # 合并 master 分支到当前分支(dev2 分支)自动合并 file1冲突(内容):合并冲突于 file1自动合并失败,修正冲突然后提交修正的结果。ubuntu@xiaozhi:~/Desktop/gitcode$ vim file1    # 解决冲突后编辑 file1 文件ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1    # 查看 file1 文件内容I am file1!aaaaaaaaaaaaI am dev!aaaaaacccccccca,b,c,d,eI am coding...Doneubuntu@xiaozhi:~/Desktop/gitcode$ git add .    # 将解决冲突后的文件添加到暂存区ubuntu@xiaozhi:~/Desktop/gitcode$ git commit -m "merge master"    # 提交合并后的修改,并添加提交注释[dev2 c00519f] merge masterubuntu@xiaozhi:~/Desktop/gitcode$ git status    # 查看当前分支状态位于分支 dev2无文件要提交,干净的工作区ubuntu@xiaozhi:~/Desktop/gitcode$ git checkout master    # 切换到 master 分支切换到分支 'master'ubuntu@xiaozhi:~/Desktop/gitcode$ git merge --no-ff -m "merge dev2" dev2    # 合并 dev2 分支到 master 分支,禁用快进模式,并添加合并注释Merge made by the 'ort' strategy. file1 | 1 + 1 file changed, 1 insertion(+)ubuntu@xiaozhi:~/Desktop/gitcode$ git status    # 查看当前分支状态位于分支 master无文件要提交,干净的工作区ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1    # 查看 file1 文件内容I am file1!aaaaaaaaaaaaI am dev!aaaaaacccccccca,b,c,d,eI am coding...Doneubuntu@xiaozhi:~/Desktop/gitcode$ git branch -d dev2    # 删除已合并的 dev2 分支已删除分支 dev2(曾为 c00519f)。

1.9删除临时分支

在软件开发中,随着不断添加新功能,我们通常希望能够在不影响主分支稳定性的情况下进行开发。每次添加新功能时,最好新建一个专门的分支,通常称为 feature 分支,在该分支上进行开发,开发完成后再合并回主分支,最后删除该 feature 分支。

然而,有时候在某个 feature 分支上开发了一半的功能,突然被产品经理叫停,需要立即停止该功能的开发。尽管该功能未完成,但是这个 feature 分支仍然需要立即删除,因为保留它已经没有意义了。这时候使用传统的 git branch -d 命令删除分支是不可行的。

这里的指令和注释,模拟了上述过程:

ubuntu@xiaozhi:~/Desktop/gitcode$ git checkout -b dev3    # 创建并切换到一个新分支 'dev3'切换到一个新分支 'dev3'ubuntu@xiaozhi:~/Desktop/gitcode$ vim file1    # 编辑 file1 文件,添加新功能的代码ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1    # 查看 file1 文件内容,确认修改I am file1!aaaaaaaaaaaaI am dev!aaaaaacccccccca,b,c,d,eI am coding...DoneI am coding... dev3ubuntu@xiaozhi:~/Desktop/gitcode$ git add .    # 将修改后的文件添加到暂存区ubuntu@xiaozhi:~/Desktop/gitcode$ git commit -m "md file1 for new features"    # 提交修改,添加提交注释[dev3 7bffbbd] md file1 for new features 1 file changed, 1 insertion(+)#新功能叫停ubuntu@xiaozhi:~/Desktop/gitcode$ git checkout master    # 切换回 'master' 分支切换到分支 'master'ubuntu@xiaozhi:~/Desktop/gitcode$ git branch -d dev3    # 尝试删除 'dev3' 分支(未合并时)error: 分支 'dev3' 没有完全合并。如果您确认要删除它,执行 'git branch -D dev3'。ubuntu@xiaozhi:~/Desktop/gitcode$ git branch -D dev3    # 强制删除 'dev3' 分支已删除分支 dev3(曾为 7bffbbd)。ubuntu@xiaozhi:~/Desktop/gitcode$

这段操作模拟了在 dev3 分支上开发新功能并提交后,尝试删除未合并的分支时出现的情况。因为 dev3 分支中的修改还未合并到 master 分支,所以需要使用 -D 参数强制删除该分支。

二、远程操作

2.1理解分布式版本控制系统

在这里插入图片描述

  1. 每个开发者都拥有完整的仓库副本: 在Git中,每个开发者克隆(clone)的不仅是项目的一个工作副本,而是整个仓库的完整副本,包括所有历史记录、分支和标签。这意味着每个开发者都可以在本地进行大部分的版本控制操作,而无需持续与中央服务器进行通信。

  2. 本地操作和快速性: Git允许开发者在本地快速执行版本控制操作,如提交(commit)、查看历史(log)、比较差异(diff)等,这些操作不会受到网络延迟的影响。开发者可以频繁地提交代码,记录项目的演变过程。

  3. 强大的分支管理: Git的分支功能极为强大和灵活,开发者可以轻松地创建、切换、合并和删除分支,而这些操作都是本地执行的。每个分支都是一个独立的实体,允许开发者在不同的功能或实验性质的工作之间进行切换,而不会干扰主分支或其他开发者的工作。

  4. 安全性和备份: 每个开发者都拥有一个完整的本地备份,这使得Git在灾难恢复和版本回滚方面非常强大。即使中央服务器出现故障或网络中断,开发者仍然可以继续工作,并且可以通过其他开发者的仓库进行恢复。

  5. 分布式协作和开发模型: Git的设计使得分布式团队能够高效协作。开发者可以通过推送(push)和拉取(pull)操作与其他仓库进行同步,分享自己的代码变更。这种方式不仅支持多人同时开发,还有助于避免单点故障和集中式系统的瓶颈问题。

Git作为分布式版本控制系统,通过其强大的分支管理、本地操作和每个开发者都拥有完整副本的特性,使得团队能够更加灵活和高效地进行协作,同时保证了代码的安全性和稳定性。这种设计理念和架构使Git成为当今软件开发行业中最流行和广泛使用的版本控制系统之一。

2.2 远程仓库

Git是一种分布式版本控制系统,这意味着同一个Git仓库可以分布到不同的机器上。最初,通常只有一台机器有一个原始版本库,其他机器可以通过“克隆”这个原始版本库来获取完全相同的版本库副本,没有主次之分。

即使只有一台电脑,也可以在不同的目录下克隆多个版本库。然而,在实际生活中,很少有人会在同一台电脑上管理多个远程库,因为这样做没有意义,而且如果硬盘出现问题,会导致所有库都受影响。因此,一般情况下,会选择一台电脑作为服务器角色,24小时开机,其他人从这个“服务器”仓库克隆一份到自己的电脑上,并将各自的提交推送到服务器仓库,也从服务器仓库中获取其他人的提交。

可以自己搭建运行Git的服务器,不过在学习Git的初期,为了简化流程,搭建服务器可能显得有些繁琐。这时,GitHub这个网站就显得非常有用了。GitHub提供Git仓库的托管服务,注册一个GitHub账号后,可以免费获得Git远程仓库,方便进行代码管理和团队协作。

2.2.1 新建远程仓库

  • 新建仓库
    在这里插入图片描述
  • 填写仓库信息
    在这里插入图片描述
  • 创建成功
    在这里插入图片描述
  • 刚创建的仓库有且只有⼀个默认的master/main分支
    在这里插入图片描述

2.2.2 克隆远程仓库

克隆/下载远端仓库到本地,需要使用git clone 命令,后面跟上我们的远端仓库的链接,远端仓库的链接可以从仓库中找到:选择“克隆/下载”获取远程仓库链接:
在这里插入图片描述

SSH协议和HTTPS协议是Git最常用的两种数据传输协议。

SSH协议利用公钥加密和公钥登录机制,具备较高的实用性和安全性。使用SSH协议时,需要在Git服务器上配置和管理公钥。用户通过生成一对公钥和私钥,将公钥添加到Git服务器的账户中,这样就可以使用私钥进行认证和数据传输。SSH协议的优点是安全性高,传输过程中数据加密,适合需要保护代码安全的环境。

HTTPS协议则相对简单,使用起来不需要额外的配置。可以直接通过克隆URL来获取代码,不涉及公钥和私钥的管理。HTTPS协议适合简单的开发和个人项目,不需要复杂的认证过程。

  • 使用HTTPS方式:
ubuntu@xiaozhi:~/Desktop/test$ git clone https://github.com/XZ293/git_test.git正克隆到 'git_test'...remote: Enumerating objects: 3, done.remote: Counting objects: 100% (3/3), done.remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0接收对象中: 100% (3/3), 完成.ubuntu@xiaozhi:~/Desktop/test$ lsgit_testubuntu@xiaozhi:~/Desktop/test$ ls git_test/README.md
  • 使用SSH方式:
ubuntu@xiaozhi:~/Desktop/test$ git clone git@github.com:XZ293/git_test.git正克隆到 'git_test'...The authenticity of host 'github.com (20.205.243.166)' can't be established.ED25519 key fingerprint is SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU.This key is not known by any other namesAre you sure you want to continue connecting (yes/no/[fingerprint])? yes      Warning: Permanently added 'github.com' (ED25519) to the list of known hosts.git@github.com: Permission denied (publickey).fatal: 无法读取远程仓库。请确认您有正确的访问权限并且仓库存在。

使用SSH方式克隆仓库,由于我们没有添加公钥到远端库中,服务器拒绝了我们的clone链接。需要我们设置一下:

  • 第一步:检查是否已经有SSH Key

    1. 打开终端。
    2. 输入以下命令查看是否已经存在.ssh目录和相应的密钥文件:
    ls -al ~/.ssh

    如果已经存在 id_rsaid_rsa.pub 这两个文件,则可以直接跳到下一步。

  • 第二步:创建SSH Key(如果不存在)

    如果在.ssh目录下没有找到 id_rsaid_rsa.pub 文件,需要生成SSH Key:

    1. 在终端中执行以下命令:
    ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
    • -t rsa 指定生成RSA密钥。
    • -b 4096 指定密钥长度为4096位(更安全的选项,也可以选择2048位)。
    • -C "your_email@example.com" 是一个注释,用来标识该密钥,可以填写你的邮箱地址或其他标识。
  1. 按照提示,在默认的.ssh目录中保存生成的密钥文件。可以选择保持默认路径和文件名,也可以根据需要修改保存路径和文件名。

  2. 如果需要设置密码保护密钥(推荐),会提示输入密码和确认密码。

  • 第三步:添加SSH公钥到远程Git仓库

在这里插入图片描述

在这里插入图片描述
添加之后就可以直接去clone了。

ubuntu@xiaozhi:~/Desktop/test$ git clone git@github.com:XZ293/git_test.git正克隆到 'git_test'...remote: Enumerating objects: 3, done.remote: Counting objects: 100% (3/3), done.remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0接收对象中: 100% (3/3), 完成.ubuntu@xiaozhi:~/Desktop/test$ lsgit_testubuntu@xiaozhi:~/Desktop/test$ ls git_test/README.md

done,成功!如果有多个人协作开发,GitHub/Gitee允许添加多个公钥,只要把每个人的电脑上的Key都添加到GitHub/Gitee,就可以在每台电脑上往GitHub/Gitee上提交推送了。

当我们从远程仓库克隆一个Git仓库后,Git会自动将本地的master分支(或更新后的默认分支名,如main)与远程仓库的相应分支(在旧版本Git中为master)建立跟踪关系,并将远程仓库的名称默认为origin。在本地,我们可以通过执行git remote命令来查看远程仓库的信息,包括其名称;若要查看远程仓库的详细信息,包括远程分支列表,可以使用git remote -v命令。

ubuntu@xiaozhi:~/Desktop/test$ cd git_test/ubuntu@xiaozhi:~/Desktop/test/git_test$ git remote originubuntu@xiaozhi:~/Desktop/test/git_test$ git remote -vorigin	git@github.com:XZ293/git_test.git (fetch)origin	git@github.com:XZ293/git_test.git (push)

上面显示了可以抓取和推送的origin的地址。如果没有推送权限,就看不到push的地址。

2.2.3向远端仓库推送

我们可以在clone到本地的仓库中新建一个文件file.txt并写入数据,提交时候要注意必须设置邮箱和用户名称。否则会报错。
将本地仓库修改推送至远端的指令:

git push <远程主机名> <本地分⽀名>:<远程分⽀名># 如果本地分⽀名与远程分⽀名相同,则可以省略冒号:git push <远程主机名> <本地分⽀名>
git push <远程主机名> <本地分⽀名>:<远程分⽀名># 如果本地分⽀名与远程分⽀名相同,则可以省略冒号:git push <远程主机名> <本地分⽀名>

这里由于我们使用的是SSH协议,是不用每⼀次推送都输入密码的,方便了我们的推送操作。如果你使用的是HTTPS协议,有个麻烦地方就是每次推送都必须输入口令。
在这里插入图片描述
在这里插入图片描述

此时远端可以看到也已经更新到最新了。

2.2.4拉取远端仓库

我们来编辑远端仓库中的file.txt然后推送提交。再通过本地将远端的改动拉取下来:
在这里插入图片描述
在这里插入图片描述
从远端向本地拉取的指令:

git pull <远程主机名> <远程分⽀名>:<本地分⽀名># 如果远程分⽀是与当前分⽀合并,则冒号后⾯的部分可以省略。git pull <远程主机名> <远程分⽀名>
ubuntu@xiaozhi:~/Desktop/test/git_test$ 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 0), reused 0 (delta 0), pack-reused 0展开对象中: 100% (3/3), 1.03 KiB | 1.03 MiB/s, 完成.来自 github.com:XZ293/git_test * branch            master     -> FETCH_HEAD   cdb1578..adc5d68  master     -> origin/master更新 cdb1578..adc5d68Fast-forward file.txt | 1 + 1 file changed, 1 insertion(+)ubuntu@xiaozhi:~/Desktop/test/git_test$ cat file.txt hello git远端修改模拟需要拉取代码(日常切忌不能在远端直接对文件进行操作)!!!!!!

2.3配置Git

在日常开发中,我们有些文件不想或者不应该提交到远端,比如保存了数据库密码的配置文件,那怎么让Git知道呢?在Git⼯作区的根目录下创建⼀个特殊的 .gitignore 文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件了。
当时创建仓库的时候就可以直接选择对应的.gitignore文件模板:
在这里插入图片描述
如果当时没有选择这个选择,在工作区创建⼀个也是可以的。无论哪种方式,最终都可以得到一个完整的 .gitignore 文件,例如我们想忽略以.so.ini 结尾所有文件,.gitignore的内容

# 省略选择模本的内容...# My configurations:*.ini*.so

创建好之后就可以把文件推送到本远端仓库了。

ubuntu@xiaozhi:~/Desktop/test/git_test$ vim .gitignoreubuntu@xiaozhi:~/Desktop/test/git_test$ cat .gitignore # 省略选择模板的内容...# My configurations*.ini*.soubuntu@xiaozhi:~/Desktop/test/git_test$ git add .ubuntu@xiaozhi:~/Desktop/test/git_test$ git commit -m "add .gitignore"[master 85fda93] add .gitignore 1 file changed, 8 insertions(+) create mode 100644 .gitignoreubuntu@xiaozhi:~/Desktop/test/git_test$ git push枚举对象中: 4, 完成.对象计数中: 100% (4/4), 完成.使用 2 个线程进行压缩压缩对象中: 100% (3/3), 完成.写入对象中: 100% (3/3), 384 字节 | 384.00 KiB/s, 完成.总共 3(差异 0),复用 0(差异 0),包复用 0To github.com:XZ293/git_test.git   adc5d68..85fda93  master -> master

我们在本地创建两个被忽略的文件,再来查看仓库状态

ubuntu@xiaozhi:~/Desktop/test/git_test$ touch aaa.soubuntu@xiaozhi:~/Desktop/test/git_test$ touch bbb.iniubuntu@xiaozhi:~/Desktop/test/git_test$ git status 位于分支 master您的分支与上游分支 'origin/master' 一致。无文件要提交,干净的工作区

此时这两个文件是无法被git管理的,也可以通过-f选项强制添加:

git add -f [filename]

也可以通过git check-ignore -v [filename]来查看文件被.gitignore文件的哪一个规则忽略:

ubuntu@xiaozhi:~/Desktop/test/git_test$ git check-ignore -v aaa.so.gitignore:7:*.so	aaa.so

设置了排除规则,也可以单独设立不排除满足规则的某个文件:

# 排除所有.开头的隐藏⽂件:.*# 不排除.gitignore!.gitignore#把指定文件排除在 .gitignore 规则外的写法就是 ! +文件名

2.4 命令配置别名

Git也给我们提供了给指令起别名的功能。
比如要将git status起别名为git st:

ubuntu@xiaozhi:~/Desktop/test/git_test$ git config --global alias.st statusubuntu@xiaozhi:~/Desktop/test/git_test$ git st位于分支 master您的分支与上游分支 'origin/master' 一致。无文件要提交,干净的工作区

--global 参数是全局参数,也就是这些命令在这台电脑的所有Git仓库下都有用。如果不加,那只针对当前的仓库起作用。

ubuntu@xiaozhi:~/Desktop/test/git_test$ git config --global alias.last 'log -1'ubuntu@xiaozhi:~/Desktop/test/git_test$ git last commit 85fda93cabce0659098f39e3665dde526ecd0c59 (HEAD -> master, origin/master, origin/HEAD)Author: 小智 <2935117143@qq.com>Date:   Tue Aug 6 09:35:23 2024 +0800    add .gitignore

🍀小结🍀

今天我们学习了"Git分支管理、远程操作相信大家看完有一定的收获。种一棵树的最好时间是十年前,其次是现在! 把握好当下,合理利用时间努力奋斗,相信大家一定会实现自己的目标!加油!创作不易,辛苦各位小伙伴们动动小手,三连一波💕💕~~~,本文中也有不足之处,欢迎各位随时私信点评指正!
在这里插入图片描述

也许您对下面的内容还感兴趣: