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

news2024/11/24 17:33:45

目录

  • 一、分支管理
    • 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		#查看当前本地所有分支
* master
ubuntu@xiaozhi:~/Desktop/gitcode$ git branch dev  	#创建新的分支 dev
ubuntu@xiaozhi:~/Desktop/gitcode$ git branch 
  dev
* master

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

ubuntu@xiaozhi:~/Desktop/gitcode$ ls .git/refs/heads/
dev  master
ubuntu@xiaozhi:~/Desktop/gitcode$ cat .git/refs/heads/*
5c846bddb4d0afc3372d2de7a0b03dd490457b76
5c846bddb4d0afc3372d2de7a0b03dd490457b76
ubuntu@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
  master
ubuntu@xiaozhi:~/Desktop/gitcode$ cat .git/HEAD   #查看HEAD指针指向
ref: refs/heads/dev

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

ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1 
I am file1!
aaaaaaaaaaaa
ubuntu@xiaozhi:~/Desktop/gitcode$ echo "I am dev!" >> file1 #修改file1文件
ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1 
I am file1!
aaaaaaaaaaaa
I 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分支的最后一次提交
68054cc7bda01f41ff5bec07c6fe2408196e607f
ubuntu@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
* master
ubuntu@xiaozhi:~/Desktop/gitcode$ git merge dev 	#使用merge将dev合并到master分支
更新 5c846bd..68054cc
Fast-forward
 file1 | 1 +
 1 file changed, 1 insertion(+)
ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1 		#dev下的提交更新到了master分支上
I am file1!
aaaaaaaaaaaa
I am dev!

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

1.5删除分支

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

ubuntu@xiaozhi:~/Desktop/gitcode$ git branch 
* dev
  master
ubuntu@xiaozhi:~/Desktop/gitcode$ git branch -d dev
error: 无法删除检出于 '/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!
aaaaaaaaaaaa
I am dev!
ubuntu@xiaozhi:~/Desktop/gitcode$ echo "aaaaaa" >>file1 
ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1 
I am file1!
aaaaaaaaaaaa
I am dev!
aaaaaa
ubuntu@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!
aaaaaaaaaaaa
I am dev!
ubuntu@xiaozhi:~/Desktop/gitcode$ echo "cccccccc" >>file1 
ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1 
I am file1!
aaaaaaaaaaaa
I am dev!
cccccccc
ubuntu@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!
aaaaaaaaaaaa
I am dev!
aaaaaa
cccccccc
ubuntu@xiaozhi:~/Desktop/gitcode$ git add .
ubuntu@xiaozhi:~/Desktop/gitcode$ git commit -m "merge dev1"
[master f7fe134] merge dev1
ubuntu@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
* master
ubuntu@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!
aaaaaaaaaaaa
I am dev!
aaaaaa
cccccccc
a,b,c,d
ubuntu@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!
aaaaaaaaaaaa
I am dev!
aaaaaa
cccccccc
ubuntu@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!
aaaaaaaaaaaa
I am dev!
aaaaaa
cccccccc
a,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!
aaaaaaaaaaaa
I am dev!
aaaaaa
cccccccc
a,b,c,d
I 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 file1
ubuntu@xiaozhi:~/Desktop/gitcode$ git status   # 再次查看工作区状态,确认是干净的
位于分支 dev2
无文件要提交,干净的工作区
ubuntu@xiaozhi:~/Desktop/gitcode$ cat file1   # 再次查看 file1 文件内容,确认没有修改丢失
I am file1!
aaaaaaaaaaaa
I am dev!
aaaaaa
cccccccc
a,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!
aaaaaaaaaaaa
I am dev!
aaaaaa
cccccccc
a,b,c,d,e
ubuntu@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!
aaaaaaaaaaaa
I am dev!
aaaaaa
cccccccc
a,b,c,d,e
ubuntu@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 file1
ubuntu@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!
aaaaaaaaaaaa
I am dev!
aaaaaa
cccccccc
a,b,c,d
I am coding...Done
ubuntu@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
  master
ubuntu@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!
aaaaaaaaaaaa
I am dev!
aaaaaa
cccccccc
a,b,c,d,e
I am coding...Done
ubuntu@xiaozhi:~/Desktop/gitcode$ git add .    # 将解决冲突后的文件添加到暂存区
ubuntu@xiaozhi:~/Desktop/gitcode$ git commit -m "merge master"    # 提交合并后的修改,并添加提交注释
[dev2 c00519f] merge master
ubuntu@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!
aaaaaaaaaaaa
I am dev!
aaaaaa
cccccccc
a,b,c,d,e
I am coding...Done
ubuntu@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!
aaaaaaaaaaaa
I am dev!
aaaaaa
cccccccc
a,b,c,d,e
I am coding...Done
I am coding... dev3
ubuntu@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$ ls
git_test
ubuntu@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 names
Are 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$ ls
git_test
ubuntu@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 
origin
ubuntu@xiaozhi:~/Desktop/test/git_test$ git remote -v
origin	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..adc5d68
Fast-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 .gitignore
ubuntu@xiaozhi:~/Desktop/test/git_test$ cat .gitignore 
# 省略选择模板的内容
...
# My configurations
*.ini
*.so
ubuntu@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 .gitignore
ubuntu@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),包复用 0
To github.com:XZ293/git_test.git
   adc5d68..85fda93  master -> master

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

ubuntu@xiaozhi:~/Desktop/test/git_test$ touch aaa.so
ubuntu@xiaozhi:~/Desktop/test/git_test$ touch bbb.ini
ubuntu@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 status
ubuntu@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分支管理、远程操作相信大家看完有一定的收获。种一棵树的最好时间是十年前,其次是现在! 把握好当下,合理利用时间努力奋斗,相信大家一定会实现自己的目标!加油!创作不易,辛苦各位小伙伴们动动小手,三连一波💕💕~~~,本文中也有不足之处,欢迎各位随时私信点评指正!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1984596.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ROS2 Humble 学习【openEuler】

ROS2 Humble 学习 1 介绍1.1 概述1.2 ROS2 详细介绍1.3 openEuler 安装 ROS2 Humble1.4 ROS2 系统架构 2 ROS2 基础2.1 节点编写、编译、运行【简单示例】节点编写节点编译 g节点运行节点编译 make节点编译 CMakeLists.txtCMake依赖查找流程Python 依赖查找流程 2.2 节点交互、…

MySQL深分页和浅分页

前言 最近有面试过也遇到了问关于深分页问题&#xff0c;在这里简单从MySQL、ES等方面分享一下自己对该问题认识和总结。 一、深分页定义 可以从ES定义上来划分浅分页和深分页的边界&#xff0c;即页数超过10000页为深分页&#xff0c;少于10000页为浅分页。 二、MySQL深分…

数字化时代:蚓链助力企业破局与腾飞!

在当今数字化浪潮汹涌澎湃的时代&#xff0c;企业面临着前新机遇与新挑战。您是否渴望在竞争激烈的市场中实现数字化弯道超车&#xff1f;是否梦想着打造专属自己的独特生意赛道&#xff1f;是否期盼着拥有专享的资源生态圈&#xff1f;如果您的答案是肯定的&#xff0c;那么蚓…

CSP - J day9

一. 题目 &#xff08;1&#xff09;早安 思路&#xff1a; &#xff08;1&#xff09;cin和scanf读入字符串时遇到空格或换行就停止读入&#xff0c;对于要读入带空格的字符串时&#xff0c;常用 两种方法&#xff1a; // 法一string s;getline( cin, s ); // 法…

OrangePi AIpro学习1 —— 烧写和ssh系统

目录 一、下载烧写工具和系统 二、烧写和启动 2.1 烧写和启动 2.2 烧写失败后的问题解决 三、串口连接到主机 3.1 串口连接到主机 四、网络连接到主机 4.1 修改香橙派IP地址 4.2 win11配置以太网静态ip 4.4 主机和香橙派直连 4.5 主机和香橙派连接到同一个路由器 五…

Hive SQL进阶:掌握间隔连续查询技巧,优化大数据分析(二)

目录 1.访问次数最多的5个用户 2.近 30 天的每日活跃用户数 3.获取1-180天注册活跃留存表 4.学生名次统计 5.最近连续3周连续活跃用户数 6.最近7天内连续3天活跃用户数 7.餐馆营业额变化增长 相关拓展 1.访问次数最多的5个用户 输出每个app 下访问次数最多的5个用户 返…

DC-7靶机渗透测试

DC-7靶机 DC: 7 ~ VulnHub 文章目录 DC-7靶机信息收集web渗透权限提升Drupal后台getshell权限提升靶机总结信息收集 经过扫描得到IP地址为192.168.78.154.其中开启了ssh和80端口,看来立足点就在于web渗透找到漏洞,获取用户密码来进行ssh连接进行寻找提权方案了使用dirb扫描…

Windows平台下内存泄漏检测工具Visual Leak detector介绍(vscode使用)

!!!此工具只能检测配合VC进行代码的内存泄漏检测 1、搜索VLD工具下载 2、配置环境变量 3、在main.cpp中加入#include<vld.h> 4、在CMakeLists.txt中添加 SET(VLD_PATH "xxx") # 链接vld静态库 target_link_libraries(${PROJECT_NAME} PRIVATE ${VLD_PATH})…

学习STM32(2)--STM32单片机GPIO应用

目录 1 引 言 2 实验目的 3 实验内容 3.1掌握STM32F103的GPIO控制 3.1.1 GPIO的分组 3.1.2 GPIO的常用功能 3.1.3 STM32单片机GPIO位结构 3.1.4 STM32单片机GPIO工作模式 3.1.5 STM32的GPIO 输出-点亮LED编程要点 使用GPIO时&#xff0c;按下面步骤进行&#xff1…

antd-5版本table组件修改滚动条样式不生效问题

问题描述 在react项目中使用antd-ProComponents组件库的Protable组件时修改table自带的滚动条样式不生效。 排查记录 一般来说直接table组件库要自定义滚动条的样式&#xff0c;只需要修改 ant-table-body 的样式即可&#xff0c;代码如下&#xff1a; .ant-table-body {&am…

pikachu文件包含漏洞

一&#xff1a;漏洞基础 程序在引用文件的时&#xff0c;引用的文件名存在可控的情况&#xff0c;传入的文件名没有经过合理的校验或校验不严&#xff0c;从而操作了预想之外的文件&#xff0c;就有可能导致文件泄漏和恶意的代码注入&#xff1b; 文件包含漏洞概念 在PHP程序…

如果忘了Linux密码如何重置?

忘记密码是我们常会遇到的情况之一&#xff0c;无论是在操作系统、网站账户、手机、电子邮件还是其他渠道上。 忘记密码是我们常会遇到的情况之一&#xff0c;无论是在操作系统、网站账户、手机、电子邮件还是其他渠道上。有时候如果密码需要符合特定的复杂性要求&#xff0c;…

【C++题解】1023. 判断素数

欢迎关注本专栏《C从零基础到信奥赛入门级&#xff08;CSP-J&#xff09;》 问题&#xff1a;1023. 判断素数 类型&#xff1a;函数&#xff0c;sqrt函数入门 题目描述&#xff1a; 任意输入一个整数&#xff0c;判断它是否为素数。是的话输出 T ,不是的话输出 F。 质数又称…

从传统监控到智能化升级:EasyCVR视频汇聚平台的一站式解决方案

随着科技的飞速发展和社会的不断进步&#xff0c;视频监控已经成为现代社会治安防控、企业管理等场景安全管理中不可或缺的一部分。而在视频监控领域&#xff0c;EasyCVR视频汇聚平台凭借其强大的多协议接入能力&#xff0c;在复杂多变的网络环境中展现出了卓越的性能和广泛的应…

Android 12系统源码_多屏幕(一)多屏幕设备显示Activity

前言 分屏&#xff1a;是指一个屏幕分出多个窗口&#xff0c;分别显示不同应用的界面&#xff0c;这在当前的手机设备中很常见。多屏&#xff1a;是指一个设备存在多个屏幕&#xff0c;这些可能是虚拟屏幕或者实体硬件屏幕&#xff0c;不同的应用同时显示在不同的屏幕中&#…

全面解析:msvcp140_atomic_wait.dll 丢失的解决之道,助你轻松应对

在尝试解决“msvcp140_atomic_wait.dll丢失”的问题时&#xff0c;首先需要确认错误信息的准确性。用户应仔细检查在启动程序或执行特定操作时是否确实出现了这一错误提示。确认错误后&#xff0c;可以进一步采取措施来解决问题。这包括检查系统日志和错误报告&#xff0c;以确…

RK3562J技术分享 | 使用SPI挂载数字式RTD温度传感器的方法

MAX31865是简单易用的热敏电阻至数字输出转换器&#xff0c;优化用于铂电阻温度检测器(RTD)。外部电阻设置RTD灵敏度&#xff0c;高精度Δ-Σ ADC将RTD电阻与基准电阻之比转换为数字输出。MAX31865输入具有高达45V的过压保护&#xff0c;提供可配置的RTD及电缆开路、短路条件检…

如何避免或者减少线上空指针问题的发生

一、背景 在我们的日常工作中&#xff0c;我们会经常遇到空指针问题&#xff0c;理论上来说只是一个判段空指针的小问题&#xff0c;但是因为这行代码的报错&#xff0c;程序中断了后面的执行&#xff0c;可能导致整体业务逻辑受影响。那在工作中我们应该如何避免&#xff0c;…

layer.load 加倒计时

实现效果 loadinglayer.load(1, {content:"",shade: [0.7, #333],time:5000,success: function(layero,index) {var i 5;var timer null;var fn function() {// 显示的提示layero.find(".layui-layer-content").html(正在连接&#xff0c;请稍等&…

谷歌突然停止为应用程序生成胖APK 只提供AAB包可能会影响用户侧载安装

谷歌最初是在 2018 年开始准备 Android App Bundle (即 AAB) 安装包&#xff0c;到 2021 年这种格式已经成为默认格式&#xff0c;开发者在提交应用程序时需要将其构建为 AAB 格式方便 Google Play 应用商店分发。 AAB 格式的优势在于适用于不同屏幕尺寸、语言、CPU 架构和 An…