git详解


参考
svn与git详解
git实战
git常用命令

1.git与svn与简介

1.1 git

    git是一种分布式版本控制系统,没有中央服务器,每个人的电脑就是一个完整的版本库,这样,工作的时候就不需要联网了,因为版本都是在自己的电脑上。既然每个人的电脑都有一个完整的版本库,多人协作(自己在电脑上改了文件A,其他人也在电脑上改了文件A)时就需要将各自的修改推送给对方。
    整个的流程如下图,其中workspace为工作区,staging为暂存区,Local repository为本地仓库区,Remote repository为远程仓库

在这里插入图片描述

1.2 git常见命令

常见命令
1.基本提交流程

当前路径:/e/testgit
1.创建版本库:会在当前目录下会多一个.git的目录,用来跟踪管理版本,不要手动乱改,会破坏git仓库
git init
2.开始工作,如创建readme.txt文件,文件内容为:1111
3.将工作添加到暂存区staging
git add readme,txt
4.将工作提交到本地仓库
git commit -m "提交说明:readme.txt提交"
5. 查看是否还有文件未提交
git status
6.修改readme.txt,再次查看,提示readme.txt文件已被修改,但是未被添加到暂存区的修改
7.差异比较:
git diff  暂存区vs工作区
git diff commit 给定提交ID vs工作区
git diff --cached commit  暂存区vs给定提交ID
git diff commit1 commit2  commit1 vs commit2
--stat  显示有多少行发生变化,简洁的展示差异
git diff HEAD~ HEAD > patch 可以通过比较差异的命令加上 > patch,导出补丁文件
git apply patch  应用补丁

2.版本回退

1.查看修改提交日志
git log 显示从最近到最远的显示日志
2.版本回退
git checkout --<filename> 放弃掉该文件(filename)还没有加入到缓存区的修改(内容修改与文件删除)
git checkout . 放弃掉所有还没有加入到缓存区的修改(内容修改与文件删除),不删除新建的文件,
刚新建的文件还未加入到git管理系统,可手动删除。

git reset HEAD filepathname 放弃指定文件的在暂存区的内容
git reset HEAD . 回退到当前版本,清除当前所有添加到暂存区的内容
HEAD 默认指向指向当前分支的最新提交,HEAD 并非只能指向分支的最顶端(时间节点距今最近的那个),
实际上它可以指向任何一个节点,它就是 Git 内部用来追踪当前位置的游标。

git reset  HEAD^ 要回退到上上个版本使用 HEAD^^,以此类推,更多,使用 HEAD~n,前n个版本
git reset commitID 回到指定版本
其他选项
–-hard:慎用,会丢弃工作区和暂存区的修改,对于未追踪的文件没有影响。
–-mixed:默认参数,可不写,将添加到暂存区的代码放入工作区,只是HEAD指向发生了变化,指向命令指定的版本。
–soft:
    工作区:修改将会原样保留,
    暂存区:如果回退之后的版本追踪了该文件,将原模原样保留在暂存区,如果回退之后的版本未追踪该文件,该文件仍然保留在暂存区,只是变为新增文件,内容为最后修改的结果。
    未被追踪的文件不受影响。
git reflog 查看所有分支的所有操作记录(包括已经被删除的commit记录和reset的操作),
弥补git log的局限性,如果回退后又想回到新版本,可以利用git reflog查询commitID

3.远程仓库

1.注册github账号,本地Git仓库和github仓库之间的传输是通过SSH加密,需要在本地创建SSH Key
ssh-keygen -t rsa –C "youremail@example.com" 在用户主目录下的.ssh目录下创建公钥和私钥
打开github的“settings”中的SSH Keys页面,点击“Add SSH Key”,黏贴id_rsa.pub的内容

2.添加远程库(本地创建了一个Git仓库后,还想在github创建一个Git仓库,且这两个仓库进行远程同步)
在github中创建一个空仓库
git remote add origin https://github.com/yourgit/testgit.git 在本地添加远程仓库

3.推送到远程
一般形式为 git push <远程主机名> <本地分支名>  <远程分支名> ,如:
git push origin master:refs/for/master 第一个master是本地分支名,第二个master是远程分支名,
refs/for--提交代码到服务器之后是需要经过code review 之后才能进行merge的,而refs/heads不需要
git push origin master 省略远程分支名,则将本地分支推送到与之存在追踪关系的远程分支(通常同名),
如果该远程分支不存在,则会被新建
git push origin :refs/for/master 省略本地分支名,则表示删除指定的远程分支,
因为这等同于推送一个空的本地分支到远程分支,等同于 git push origin --delete master
git push origin 若当前分支与远程分支存在追踪关系,则本地分支和远程分支都可以省略,
将当前分支推送到origin主机的对应分支 
git push 如果当前分支只有一个远程分支,主机名可省略,可以使用git branch -r ,查看远程的分支名

git push -u origin master 本地库的内容推送到远程,实际上是把当前分支master推送到远程
-u: 当前分支与多个主机存在追踪关系,-u参数指定一个默认主机(upstream server),可简化推送、拉取命令
git push --all origin 不管是否存在对应的远程分支,将本地的所有分支都推送到远程主机
git push --force origin 推送前需要本地先git pull更新到跟服务器版本一致,如果本地版本库比
远程服务器上的低,会提示git pull更新,如果要不更新提交,那么可以使用这个命令。

4.从远程克隆
git clone https://github.com/yourgit/testgit2

4.分支相关

1.创建分支
git branch b1 创建分支b1 
git checkout -b dev 创建分支,并切换到新分支dev
2.查看当前所在分支
git branch 列出所有的分支,当前分支前面会添加一个星号
3.切换分支
git checkout master
4.在dev分支上进行开发,修改readme.txt,并add,commit
5.dev分支工作完成,切换到master分支,master上readme.txt内容还是原来的
git merge dev 把dev分支上的内容合并到分支master上,git merge 用于合并指定分支到当前分支上,
会提示Fast-forward信息,告诉我们,这次合并是“快进模式”,直接把master指向dev的当前提交,速度很快
6.删除分支
git branch -d dev 合并完成后,可以删除dev分支
7.解决冲突
git checkout -b fenzhi1 创建并切换到该分支,修改readme.txt,并add,commit
git checkout master 切换到master分支,修改readme.txt(不一样的修改),并add,commit
git merge fenzhi1 在master分支上,把dev分支合并到master,会提示冲突
cat readme.txt 会显示具体冲突内容,Git用<<<<<<<=======>>>>>>>标记出不同分支的内容,
根据实际情况,再次修改read.txt文件,解决冲突,并add,commit
8.分支管理策略
通常合并分支时,git一般使用”Fast forward”模式,此模式下,删除分支后,会丢掉分支信息,
使用参数–no-ff禁用“Fast forward”模式,可保存之前的分支历史,能够更好的查看 merge历史和branch状态。
参考:https://blog.csdn.net/weixin_42338707/article/details/107068695
9.bug分支
开发中,bug可通过一个临时分支来修复,修复完成后,合并分支,然后将临时的分支删除掉
在dev分支上开发到一半突然出现404问题需要修复,而此时dev分支上的工作还没完成不能提交,
Git提供stash功能,可以把当前工作现场 ”隐藏起来”,等以后恢复现场后继续工作
git stash
修复过程:首先确定在那个分支上修复,比如是在主分支master上来修复的,就在master分支上创建临时分支
git checkout master
git checkout -b issue-404 然后修复对应bug,并add,commit
修复完成后,切换到master分支上,并完成分支合并,最后删除issue-404分支
回到dev上干活:需要恢复工作现场
git checkout dev
git stash list 查看之前保存的工作现场list
git stash apply 恢复方法一,恢复后,stash内容不删除,需要使用命令git stash drop来删除。
git stash pop 恢复方法二,恢复的同时把stash内容也删除了。

5.多人合作

经典流程:用git push origin branch-name推送自己的修改,如果推送失败,则因为远程分支比你的本地更新早,需要先用git pull试图合并。如果合并有冲突,则需要解决冲突,并在本地提交。再用git push origin branch-name推送。
从远程库克隆时候,Git自动把本地的master分支和远程的master分支对应起来,远程库的默认名称是origin
1.查看远程库
git remote
git remote –v 详细信息
2.推送分支到远程
推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支。
master分支是主分支,要时刻与远程同步。修复bug分支不需要推送到远程去,合并到主分支推送到远程。
git push origin master
git push origin dev
3.多人协作
可以模拟另外一个同事,新建一个目录名字叫testgitb,将项目克隆到testgitb目录下
另一个同事要在dev分支上做开发,必须把远程的origin的dev分支弄到本地来,可以使用命令创建本地dev分支:
git checkout –b dev origin/dev
同事在dev分支上开发,完成后将dev分支推送到远程
我也在dev分支上开发,完成后将dev分支推送到远程,送失败,因为我的同时最新提交的和我试图推送的有冲突
git pull 把最新的提交从origin/dev抓下来,然后在本地合并,解决冲突,再推送
git branch --set-upstream dev origin/dev 解决git pull失败,未指定本地dev分支与远程dev分支的链接
git pull 设置链接后,再次把最新的提交从origin/dev抓下来,然后在本地合并,解决冲突,再推送

常用git命令速查
在这里插入图片描述

1.3 git命令比较与补充

rebase和merge的区别
   总的原则:只对尚未推送或分享给别人的本地修改执行变基操作清理历史,从不对已推送至别处的提交执行变基操作,这样,你才能享受到两种方式带来的便利。
merge的三种选项参数
   Fast-forward: master分支合并dev分支时候发现, master当前节点就是dev分支的根节点,那么 master快速移动头指针到 dev的位置,所以 Fast-forward 并不会发生真正的合并,只是通过移动指针造成合并的假象。通过 Fast-forward 模式产生的合并可以产生干净并且线性的历史记录。
在这里插入图片描述   non-Fast-forward: 当合并的分支跟 master 不存在共同祖先节点的时候,这时候在 merge 的时候 git 默认无法使用 Fast-forward 模式。如下图,可以看到 master 分支已经比 dev 快了2个版本,master 已经没办法通过移动头指针来完成 Fast-forward,所以在 master 合并 dev 的时候就不得不做出真正的合并.
在这里插入图片描述手动设置合并模式:
   --ff-only Fast-forward 模式:只会按照 Fast-forward 模式进行合并,如果不符合条件(并非当前分支的直接后代),则会拒绝合并请求并且退出。适合小型团队,并且追求干净线性 git 历史记录
   --ff 自动合并模式:默认使用,当合并的分支为当前分支的后代的,会执行 --ff 模式,如果不匹配则执行 --no-ff合并模式。不追求线性的 git 历史记录,要体现相对真实的 merge 记录。
   --no-ff 非 Fast-forward 模式:在任何情况下都会创建新的 commit 进行多方合并(即使被合并的分支为自己的直接后代)。大型团队,并且要严格监控每个功能分支的合并情况

rebase原理
1.首先找到这两个分支(即当前分支 dev、变基操作的目标基底分支 master)的最近共同祖先 2
2.对比当前分支相对于该祖先(2)的历次提交(5,6),提取相应的修改并存为临时文件
3.将当前分支指向目标基底 (4),并在基底(4)上依序应用前面另存为临时文件的修改
5.回到 master 分支,进行一次快进合并。

在这里插入图片描述fetch和pull的区别
   git pull 相当于 git fetch + git merge,但本质不同。实际使用中 使用git fetch 更安全 在merge之前可以看清楚 更新情况 再决定是否合并。
   git fetch作用为更新关联的远程版本ID

git fetch origin dev 拉取远程库,更改远程库关联库commitID,
如远程库commitID=2 远程关联库commitID=2 本地commitID=1
git merge FETCH_HEAD 合并FETCH_HEAD指针到HEAD指向的分支的当前版本,本地产生新版本,
如远程库commitID=2 远程关联库commitID=2 本地commitID=3

   git pull是直接把远程仓库版本迭代到本地仓库和远程仓库关联库上

git pull 如远程库commitID=2 远程关联库commitID=1 本地commitID=1,
变成如远程库commitID=2 远程关联库commitID=2 本地commitID=2

可配合下图食用
在这里插入图片描述
reset和revert的区别
    工作时会出现错误提交的情况,此时我们希望能让程序回到提交前的样子,github提供了两种解决方法:回退(reset)和反做(revert).
   git reset的作用是修改HEAD的位置,即将HEAD指向的位置改变为之前存在的某个版本
   git revert是用于“反做”某一个版本,以达到撤销该版本的修改的目的
参考:https://blog.csdn.net/yxlshk/article/details/79944535

cherry-pick
    对于多分支的代码库,将代码从一个分支转移到另一个分支是常见需求。这时分两种情况。一种情况是,你需要另一个分支的所有代码变动,那么就采用合并(git merge/rebase)。另一种情况是,你只需要部分代码变动(某几个提交),这时可以采用 Cherry pick。

git cherry-pick commitID 将指定的提交commitID ,应用于当前分支。这会在当前分支产生一个新的提交
更多可参考:http://www.ruanyifeng.com/blog/2020/04/git-cherry-pick.html

submodule
    面对比较复杂的项目,我们有可能会将代码根据功能拆解成不同的子模块。主项目对子模块有依赖关系,却又并不关心子模块的内部开发流程细节,Git Submodule 允许一个git仓库,作为另一个git仓库的子目录,并且保持父项目和子项目相互独立。
参考:https://www.jianshu.com/p/f8a55b972972/

squash
    想将本地开发分支的内容合并到master主线分支上,并且期望将一个功能的所有提交压缩成一个commit
参考:https://www.jianshu.com/p/a122aa26dd2e

1.4 svn

    svn是集中式版本控制系统,版本库是集中放在中央服务器的,编码前要先将中央服务器上最新的版本更新到自己电脑上,然后再编码,编码完后,需要将自己的新代码推送到中央服务器。集中式版本控制系统是必须联网才能工作,如果在局域网还可以,带宽够大,速度够快,如果在互联网下,如果网速慢的话,容易受限。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值