作者:Rhythm-2019
邮箱:rhythm_2019@163.com
最近更新:2020.01.03
感觉如同两三个月没写博客了,最近始终要去实验室做毕设,之前在 Gitee 上看见一个我的项目Learn Git Branching
,是一个可视化的 Git 学习平台。所以除夕找了两天来学习一下。尽管感觉当前工作可能面对的问题会更简单一些,也没有说教程外面这么直观,然而打好根底嘛,大家也能够去体验一下
根底指令
git commit
比照新旧仓库文件的内容产生一份提交记录,新的提交记录指向旧的提交记录
git branch
在以后最新提交记录中创立一个新的正本,以新的名称命名
git checkout
用于切换分支,git checkout - b 能够创立并切换到新的分支
git marge < 援用 >
以后分支和新分支合并,在 以后分支上 产生一个提交记录,该提交记录指向两个分支的上一个节点
因为以后 master 上蕴含了所有的提交,再次合并 Git 什么都不会做
git rebase
让两个分支合体,让其看上去像是线性开发的(实际上是并行的)
留神,git rebase <ref>
是将 HEAD 指向记录及其之前的记录复制到 ref
指定地位上
操作分支
上面介绍一些分支上的操作
HEAD
咱们首先看一下“HEAD”。HEAD 是一个对以后检出记录的符号援用 —— 也就是指向你正在其根底上进行工作的提交记录。
HEAD 总是指向以后分支上最近一次提交记录。大多数批改提交树的 Git 命令都是从扭转 HEAD 的指向开始的。
HEAD 通常状况下是指向分支名的(如 bugFix)。在你提交时,扭转了 bugFix 的状态,这一变动通过 HEAD 变得可见。
拆散的 HEAD 就是让其指向了某个具体的提交记录而不是分支名。在命令执行之前的状态如下所示:
HEAD -> master -> C1
HEAD 指向 master,master 指向 C1
输出 git checkout C1
后
HEAD -> C1
对于不同的提交记录,咱们能够通过 git log
晓得他的哈希值,而后应用 git checkout
指向后进行操作 AD
集体对 HEAD 和分支的了解:我感觉他们都像是一个指针,他们都能够指向提交记录,然而 HEAD 甚至能够指向分支,咱们能够应用
git checkout < 分支 >
对 HEAD 进行拆散,拆散后分支就不随着 HEAD 的挪动而挪动了,包含提交挪动
绝对援用
咱们应用 git log
会查到每次提交的哈希值,因为哈希值比拟长,如果咱们向疾速让 HEAD 指向上一次或几次提交,能够间接应用上面两个操作符号
^
上一个父节点(如果有两个父节点请应用^1、^2
来示意)~
上几个父节点,如上两个父节点能够应用~2
示意
这两个符号反对连锁操作
操作分支
咱们当初能够应用 checkout
轻松操作 HEAD
了,咱们同样能够应用git branch -f < 分支 > < 提交记录 >
,让某个分支回到某个记录上,例如上面的练习,操作左边的 HEAD 和分支是的他变成右边红色底色的模样
我的答案是
git branch -f master C6
git checkout HEAD^
git branch -f bugFix HEAD^
撤销分支
如果在本地,咱们能够应用 git reset < 指标提交记录 >
对以后提交记录的 下一个记录及前面的所有记录 进行撤回操作,如果你须要对近程仓库进行操作,则须要应用 git revert
进行撤销,撤销后会产生一个新的提交记录便于你进行提交
大家能够从上面的形容中看出两者区别
大家要留神 HEAD 的地位,reset 后的参数是指指标地位
总结一下就是 reset
只对本地进行撤销,revert
针对近程仓库进行撤销
挪动提交记录
应用 git charry-pick < 记录 1 > < 记录 2 >...
能够疾速将提交记录复制到以后分支地位
当然啦,当你须要复制的记录比拟多,你能够应用交互式的 rebase
实现,指令为git rebase -i < 指标援用 >
,Git 会弹出一个抉择窗口,他会让你编辑以后 HEAD 指向及以前的记录供你进行编辑,编辑好后帮你复制到指标援用前面
当你的我的项目呈现了 BUG 你想要把他修复,你在代码外面加了很多输入语句,提交了一次记录,批改好 BUG 在提交一次。显然你是心愿将第二次提交放入 master
,这时就须要应用git cherry-pick
和git rebase -i
了
咱们总结一下 rebase
的用法吧:
git rebase <ref>
将以后的 HEAD 指向的提交记录(蕴含之前的记录)复制到 ref 前面git rebase <to> <from>
将form
指向的记录(包含之前的)复制到to
前面git rebase -i <ref>
与第一个指令一样,只是提供了 UI 界面能够删除两头的某些记录
实战练习
对于咱们刚刚学习的两个指令
git cherry-pick <record...>
git rebase -i <record>
在配合上咱们之前学习的
git checkout <record>
git branch -f < 分支 > <record>
咱们能够轻松的实现所有的提交记录变更
练习 1
例如上面这个练习,在咱们开发中也很常见,就是程序员 1 实现了图片代码编写并创立 newImage
分支提交了本人的代码,程序员 2 在 newImage
分支根底上创立了新的分支 caption
并提交了本人新的代码,当初主管感觉程序员 1 的代码写的有问题,须要进行批改并整合程序员 2 的代码
所以我的指令是
git rebase -i master # 调整 C2 C3 的程序使得 C2 是最新的
git commit –amend # 更新 C2
git rebase -i master # 将 C2 C3 调整回来
git branch -f master caption # 让 master 指向 caption 的指向
如果程序员 1 和程序员 2 开发不同的模块,这样调整没什么问题,然而如果他们对同一个代码进行了批改可能会造成代码抵触
更好的应该是应用cherry-pick
,指令如下
git checkout master # 让 HEAD 指向 maser 指向的记录
git cherry-pcik newImage # 复制 newImage 到 master
git commit --amend # 更新 newImage
git cherry-pick caption # 复制 caption
你会发现应用 cherry-pick
后,分支的指向都会及时更新
练习 2
再如须要你合并上面所有分支的内容
答案是
git rebase master bugFix
git rebase bugFix side
git rebase side another
git rebase naster another # 更新 master 到最新
练习 3
产生上面三个分支
治理只能应用 cherry-pick
复制了,答案是:
git checkout one
git cherry-pick C4 C3 C2
git checkout two
git cherry-pick C5 C4 C3 C2
git branch -f three C2
里程碑
你会发现分支和 HEAD 都会随着提交而挪动,当我的项目做到肯定水平要发一个大版本的时候吗,你心愿用一个标签示意这个大版本的提交记录的话,能够应用 git tag < 标签 > < 援用 >
来标识,该标签永远指向该提交记录,因而被称为里程碑
Git 还提供了一个指令git describe <ref>
,用于查问间隔该提交最近的里程碑和间隔他的步长
近程仓库
因为咱们当初须要进行合作开发,所以代码须要放在仓库进行治理,近程仓库有上面两个特点,我间接援用教程的话啦
- 首先也是最重要的的点, 近程仓库是一个弱小的备份。本地仓库也有复原文件到指定版本的能力, 但所有的信息都是保留在本地的。有了近程仓库当前,即便失落了本地所有数据, 你仍能够通过近程仓库拿回你失落的数据。
- 还有就是, 近程让代码社交化了! 既然你的我的项目被托管到别的中央了, 你的敌人能够更容易地为你的我的项目做奉献(或者拉取最新的变更)
克隆我的项目
咱们能够应用 git clone url
克隆一个我的项目
近程分支
与本地分支不同,近程分支个别以 <remote_name><branch_name>
命名,remote_name
个别是 origin
示意
当你应用
git checkout o/master
的时候会主动拆散出 HEAD,对于本地分支则会让 HEAD 指向 master,这是对近程分支的一种爱护,即近程分支不能被挪动
近程分支反映了近程仓库在你 最初一次与它通信时 的状态,咱们能够从近程仓库中获取数据或提交数据
获取数据
咱们能够应用 git fetch
获取最新的仓库,fetch
会帮忙咱们实现两件事
- 从近程仓库下载本地仓库中缺失的提交记录
- 更新近程分支指针(如
o/master
)
聪慧的你可能以及发现了本地分支 master
没有更新,fetch
只会更新近程分支
这其实十分常见,比方我写某局部代码写了比拟久,共事在我提交之前提交了更新的代码,那我应该这样做
git fetch
更新o/master
分支内容git merge o/master
将最新代码合并到以后我本地的最新提交中
大家能够看上面两幅图,图一是还没输出指令之前
执行后
其实 Git 提供了 pull
指令就是合并了这两条指令
提交代码
咱们能够应用 git push
提交你的代码,代码同步实现后,近程分支会自动更新到最新状态
然而个别状况是你上传代码时发现同时比你先提交但你又没及时拉下最新的代码,咱们须要先将把最新的代码拉下来,而后调整一下程序
git fetch
git rebase o/master
如果你只是简答的应用 git pull
,再push
的话成果如下
这样近程仓库的代码记录会比拟乱,所以大家还是先应用 git fetch
来下最新的代码,而后应用 rebase
调整程序后再push
,其中
git fetch
git rebase o/master
能够简写成git pull --rebase
例如这里须要你合并所有的分支并提交
咱们只须要应用 rebase
合并就好
git fetch
git rebase o/master side1
git rebase side1 side2
git rebase side2 side3
git rebase side3 master
git push
有同学可能会问能不能应用 merge
来调整 rebase
,其实必定是能够的,rebase
有本人的优缺点
- 长处:线性整洁
- 毛病:批改了提交程序
push
有里两个参数,第一个是 remote
的名称,默认origin
,第二个是你须要提交的分支名称,你肯定见过这个
git push origin master
把这个命令翻译过去就是:
切到本地仓库中的“master”分支,获取所有的提交,再到近程仓库“origin”中找到“master”分支,将近程仓库中没有的提交记录都增加下来,搞定之后通知我。
Git 还提供设置提交映射的形式,girt push orgin < 本地 >:< 近程 >
,这样咱们能够将本人的分支间接提交到 master 下面
其实 git fetch
也有相似的性能,git fetch origin < 近程 >:< 本地 >
能够指定跟新哪个分支
留神:如果你应用 git fetch origin master
这种写法挪动的是近程分支 o/master
,如果你应用的是 `git fetch origin < 近程 >:< 本地 >
的话挪动的是本地分支
git pull
也有相似的性能,大家能够去摸索一下
这两个命令还有两个非凡用法:
git psuh origin : 分支 # 删除本地和近程分支
git fetch origin : 分支 # 创立本地分支
近程跟踪
其实我也在好奇 Git 怎么就晓得 master
对应 o/master
的呢?原来是你执行 git clone
的时候就曾经默认绑定了,也就是本地分支 master
跟踪近程分支 o/master
。咱们有没有方法创立本人的分支,让本人的分支也跟着o/master
呢?
git checkout -b < 新分支 > o/master
git branch -u o/master < 新分支 >
删除文件
平时我大手大脚的不小心把一些不该提交的货色提交了该怎么办
- 如果你只是应用
git add
退出了暂存区,你能够应用git rm
及时删除文件 - 如果你曾经
commit
了,你须要撤销这次commit
,这个上面讲 - 如果你曾经
push
了,则须要执行上面命令git rm -r –cached a/2.txt // 删除 a 目录下的 2.txt 文件 删除 a 目录 git rm -r –cached a
git commit -m “ 删除 a 目录下的 2.txt 文件 ”用 - r 参数删除目录,
git rm --cached a.txt
删除的是本地仓库中的文件,且本地工作区的文件会保留且不再与近程仓库产生跟踪关系,如果本地仓库中的文件也要删除则用git rm a.txt
撤销文件操作
这路分几种状况哈
- 当你在工作区批改了某个文件,而后忽然想撤回到刚拉下来的时候的墨阳
git checkout — filename
- 如果你批改文件后
add
到暂存区了须要撤回到最后的样子git reset HEAD filename
- 当初你曾经
commit
了,但你想回去依据下面所学,这里能够间接撤销这次提交,而后再从暂存区中撤回,所以命令是
git reset –hard filename
- 曾经
push
了git revert HEAD^
- 撤回完悔恨了,又想回去
git reflag # 查出刚刚指向指令的 coomitId
git reset -hard <commit_id>
值得一提的是
commit -a
能够间接将这次提交追加到上一次中
参考
- Git 指令和办法大全:https://www.cnblogs.com/miracle77hp/articles/11163532.html
- Learn Git Branching:https://oschina.gitee.io/learn-git-branching/