[toc]
chapter(十)
10.1 如何管理分支
在实际的开发过程中,可能会产生很多很多分支,尤其是在多人团队的合作中,大家都在各自的分支干活,等干的差不多了就进行合并。 为了避免出现错误:有一种合理的分支管理方法是非常重要的。 根据上面的图片,提出的一种管理方法是: 每个人都在dev分支下干活,各自有各自的分支。
比如说李明在自己的分支干活,感觉差不多了,就把自己分支的内容合并到dev中。王二也是如此。 这样的好处是,dev分支的内容是总在变得,但是master是不怎么变得。这样遇到代码新版本生成时,只需要把dev分支合并到master中!
10.2 策略1:合并分支可Fast forward模式
还记得上一章的合并分支是怎么做的吗?
命令git merge <分支名>
可以合并某分支到当前分支
合并完后,我们就把那个分支删除掉了。是吧!
命令git branch -d <分支名>
可以删除分支。
但是,这里有一个隐含的情况,那就是在删除分支后,我们曾经创建过这个分支的所有信息就都丢失了。
可是,有时候这些被删除的分支实在是有点重要!比如我们要版本回退到被删除的分支,那就完蛋了!
那有没有什么方法,可以保留呢?
方法肯定是有的。
但请允许我说下什么是Fast forward模式
?
默认情况下,合并分支,Git都会使用Fast forward模式
,就是因为这种模式的存在,所以才在删除分支后,丢失了信息。
所以,思路就很清晰了,我们不使用Fast forward模式
进行分支合并不就可以了。
Git提供给我们的方法是:增加参数--no-ff
,采用这种方式,Git在合并的同时还有生成一个新的git commit
废话不多说,直接开干:
toto@pc:~/code/testGit$ git switch -c dev
Switched to a new branch 'dev'
toto@pc:~/code/testGit$ vim helloword.cpp
toto@pc:~/code/testGit$ cat helloword.cpp
#include<iostream>
int main()
{
std::cout << "This is a program that test Git!" << std::endl;
std::cout << "test git status" << std::endl;
std::cout << "test git status2" << std::endl;// 新增的一行
std::cout << "test new branch!" << std::endl;
std::cout << "fix conflict!" << std::endl;
std::cout << "test --no-ff!" << std::endl;
int a = 1;
return 0;
}
toto@pc:~/code/testGit$ git add helloword.cpp
toto@pc:~/code/testGit$ git commit -m "test --no-ff!"
[dev 578163f] test --no-ff!
1 file changed, 1 insertion(+)
上面是直接创建并切换一个新分支dev,然后修改helloword.cpp
文件,并提交。
toto@pc:~/code/testGit$ git switch master
Switched to branch 'master'
toto@pc:~/code/testGit$ git merge --no-ff -m "merge with --no-ff!" dev
Merge made by the 'recursive' strategy.
helloword.cpp | 1 +
1 file changed, 1 insertion(+)
切换会master
分支,并把dev分支合并到当前分支,注意增加了参数--no-ff
,因为合并后进行提交,所以增加了-m "merge with --no-ff!"
toto@pc:~/code/testGit$ git log --graph --pretty=oneline --abbrev-commit
* fe7b46e (HEAD -> master) merge with --no-ff!
|\
| * 578163f (dev) test --no-ff!
|/
* 87b067d fixed conflict!
|\
| * 33c858c test conflict branch
* | d70cae4 test conflict branch in master
|/
* 828ea5e test new branck
* 05e641d remove deleteFile.txt
* 190efbd test deleted file
* 7064df2 understand stage
* 74aada6 test git status2
* 2fe4439 add new line that test git status
* 01630fb test Git program
git log
后的结果如上。
10.3 策略2:有时合并的分支可以强行删除
有时候在软件开发过程中,会遇到这样的情况:
当你在一个创建的分支里进行开发某个功能, 你感觉没啥问题了,就把当前分支合并到dev
中,可是情况突然改变,比如这该功能老板说不需要了,那怎么办?
别担心,Git提供了我们该命令:即git branch -d
强行删除
快点跟着实践下!
toto@pc:~/code/testGit$ git switch -c newfeature
Switched to a new branch 'newfeature'
toto@pc:~/code/testGit$ git branch
dev
master
* newfeature
toto@pc:~/code/testGit$ vim newFunction.txt
toto@pc:~/code/testGit$ cat newFunction.txt
Test forcibly delete
toto@pc:~/code/testGit$ git add newFunction
fatal: pathspec 'newFunction' did not match any files
toto@pc:~/code/testGit$ git add newFunction.txt
toto@pc:~/code/testGit$ git commit -m "Test forcibly delete!"
[newfeature f86af87] Test forcibly delete!
1 file changed, 1 insertion(+), 1 deletion(-)
上面的示例先是创建了一个新分支git switch -c newfeature
然后增加了一个新文件vim newFunction.txt
,进行add
和commit
toto@pc:~/code/testGit$ git switch dev
Switched to branch 'dev'
toto@pc:~/code/testGit$ git branch
* dev
master
newfeature
toto@pc:~/code/testGit$ git branch -d newfeature
error: The branch 'newfeature' is not fully merged.
If you are sure you want to delete it, run 'git branch -D newfeature'.
toto@pc:~/code/testGit$ git branch -D newfeature
Deleted branch newfeature (was f86af87).
toto@pc:~/code/testGit$ git branch
* dev
master
然后我们切换到dev
分支,准备合并。
可老板说,这个功能需要取消掉,所以我们不能合并了!
先用之前的删除方法git branch -d newfeature
,试试:
结果发现报错:这个分支还没有合并,如果确定要删除,请用’git branch -D newfeature’
用完之后,可以看到确实删除了!
done!
10.4 策略3:临时stash(储藏)分支
在实际开发中,会遇到这样的情况: 比如正在dev分支进行开发,还没有进行提交。但是你的boss说,前面的代码有bug,需要赶紧修复。 可问题是你在dev分支的工作刚进行了一半,你还不想提交,但你又不得不去处理bug。
放轻松,Git已经为我们想好了招:
那就是使用命令:git stash
,把当前的工作现场储存下来,等以后需要在把这个现场恢复。这就类似一个快照
我们实际模拟下这个情况,直接干吧:
toto@pc:~/code/testGit$ git status
On branch dev
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.txt
no changes added to commit (use "git add" and/or "git commit -a")
可以看到,假设我现在正在dev
分支进行开发,此时的状态是我还没有进行提交,也不想提交。
我现在需要使用命令:git stash
进行一个快照。把当前的现场保存下来。
toto@pc:~/code/testGit$ git stash
Saved working directory and index state WIP on dev: 0806247 Test forcibly delete
toto@pc:~/code/testGit$ git status
On branch dev
nothing to commit, working tree clean
可以看到此时的分支是干净的。
将当前现场保存下来,我就赶紧去处理bug。假设bug在master
分支上,我就从master
分支上创立新的临时分支,进行修改。
toto@pc:~/code/testGit$ git switch master
Switched to branch 'master'
toto@pc:~/code/testGit$ git switch -c bug001
Switched to a new branch 'bug001'
可以看到,我已经创建且切换到临时分支’bug001’上了。
现在开始进行bug修复,即在README.txt
中增加一句话Repair BUG success !
,然后进行提交。
toto@pc:~/code/testGit$ vim README.txt
toto@pc:~/code/testGit$ cat README.txt
This document is a description!
The name is README.txt!
Repair BUG success !
toto@pc:~/code/testGit$ git add README.txt
toto@pc:~/code/testGit$ git commit -m "Repair bug success!"
[bug001 6512255] Repair bug success!
1 file changed, 2 insertions(+)
修改完,切换回master
,合并,并删除分支bug001
toto@pc:~/code/testGit$ git switch master
Switched to branch 'master'
toto@pc:~/code/testGit$ git merge --no-ff -m "merged bug001" bug001
Merge made by the 'recursive' strategy.
README.txt | 2 ++
1 file changed, 2 insertions(+)
toto@pc:~/code/testGit$ git branch -d bug001
Deleted branch bug001 (was 6512255).
ok!bug修复完毕,可以王者回归dev
分支了:
toto@pc:~/code/testGit$ git switch dev
Switched to branch 'dev'
toto@pc:~/code/testGit$ git status
On branch dev
nothing to commit, working tree clean
toto@pc:~/code/testGit$ git stash list
stash@{0}: WIP on dev: 0806247 Test forcibly delete
可以看到git status
后是干净的,这是因为我们刚才建立了一个快照。
git stash list
看下,可以发现,刚才那个快照的信息出来了。
此时恢复之前的工作状态有两种方法:
git stash apply
恢复,但是恢复后,stash
内容并不删除,你需要用git stash drop
来删除;- 用
git stash pop
,恢复的同时把stash
内容也删了:
toto@pc:~/code/testGit$ git stash pop
On branch dev
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.txt
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (517500724500357c5cd4c97579ec1683ab8beb6a)
toto@pc:~/code/testGit$ git stash list
toto@pc:~/code/testGit$
这两种恢复的方法区别是很明显的,可以根据实际情况进行选择。 这里不再演示方法1。
10.5 提交远程仓库Github
当在本地把代码修改的差不多了,可以选在将代码托管到Github中,方便其他人使用。
如果想查看远程仓库的信息,可以使用git remote
或者,用git remote -v
显示更详细的信息。
origin git@github.com:xxxx.git (fetch)
origin git@github.com:xxxx.git (push)
可以看到上面的代码有抓取和推送的origin的地址。如果没有推送权限,就看不到push的地址。
推送分支到Github使用的命令:git push origin master
,这是把master分支推送上去
如果想推送dev分支,那就是git push origin dev
10.6 总结
- 管理分支好的方法是:都在
dev
分支进行写代码,每个人干完活,都提交到dev
中,只有在代码进行重大改变的时候,在提交到master
中 - 建议分支合并的时候,增加参数`–no-ff’
- 如果要丢掉一个没有合并的分支,可以使用’git branch -D newfeature’可以强行删除分支。如何合并了,直接版本回退。
- 使用命令:
git stash
,可以把当前的工作现场储存下来,等以后需要在把这个现场恢复,恢复可用git stash apply
和git stash pop
。 - 查看远程库信息,使用
git remote -v
git push origin branch-name
可以从本地推送分支。
Git学习总结:
这系列文章都是自己的学习总结,这部分内容都是很基础的,也是在日常中普遍使用的,其实Git还有很多操作技巧,我是觉得作为新手,没必要知道的太详细。当自己使用的时候,直接Google下就好。 本人将其公开的目的:
- 是因为想帮助更多的人;
- 是因为互联网开源的精神;
- 是证明自己还存在于世。 系列文章如果要转载,请联系我。
本系列主要借鉴了:《廖雪峰Git教程》《精通Git》等
如果想对Git的基本原理深入了解,可以手写一个简易版的Git