git游戏练习

提交
git commit
 
创建一个到名为 newImage 的分支。
git branch newImage
创建分支后不切换分支就会停留在当前目录下,那如何进入新的分支呢?
 
使用git checkout 分支名来切换分支
创建一个名为newImage的分支
git checkout newImage
如果你想创建一个新的分支同时切换到新创建的分支的话,可以通过  :
git checkout -b 分支名
来实现。
 
 
如何合并分支?
合并分支需要先进入到其中一个需要合并的分支,然后使用:
git merge 另一个需要合并的分支名称
 
这就合并了2个分支,一个已经进入的需要合并的分支和另一个需要合并的分支。
第二种合并分支的方法是先进入到其中一个需要合并的分支,然后使用:
git rebase 另一个需要合并的分支名称
这就合并了2个分支,一个已经进入的需要合并的分支和另一个需要合并的分支。
 
HEAD
HEAD 是一个对当前检出记录的符号引用 —— 也就是指向你正在其基础上进行工作的提交记录。
分离HEAD
分离的 HEAD 就是让其指向了某个具体的提交记录而不是分支名。
比如说:
现在HEAD在bugFix上,需要分离HEAD直接切换git checkout c4
现在HEAD分离到c4上了
 
操作符 (^)
把这个符号加在引用名称的后面,表示让 Git 寻找指定提交记录的父提交。所以 master^ 相当于“master 的父节点”。master^^ 是 master 的第二个父节点现在咱们将HEAD切换到 master 的父节点
git checkout master^
 

“~”操作符

如果你想在提交树中向上移动很多步的话,敲那么多 ^ 貌似也挺烦人的,Git 当然也考虑到了这一点,于是又引入了操作符 ~。
该操作符后面可以跟一个数字(可选,不跟数字时与 ^ 相同,向上移动一次),指定向上移动多少次。
 
咱们用 ~<num> 一次后退四步。
git checkout HEAD~4
一次性就移动了4步
 
强制让某一个分支移动(无论记录点*在不在该分支上)
使用相对引用最多的就是移动分支。可以直接使用 -f 选项让分支指向另一个提交。例如:
git branch -f master HEAD~3
上面的命令会将 master 分支强制指向 HEAD 的第 3 级父提交。或者创建一个master并移动到HEAD 的第 3 级父。
强制移动某一节点
git branch -f 需要移动的节点名  移动到的节点名
 
 

撤销变更(git reset,git revert)

在 Git 里撤销变更的方法很多。和提交一样,撤销变更由底层部分(暂存区的独立文件或者片段)和上层部分(变更到底是通过哪种方式被撤销的)组成。
主要有两种方法用来撤销变更 —— 一是 git reset,还有就是 git revert。
git reset 通过把分支记录回退几个提交记录来实现撤销改动。你可以将这想象成“改写历史”。git reset 向上移动分支,原来指向的提交记录就跟从来没有提交过一样。
git reset HEAD~1
 
Git 把 master 分支移回到 C1;现在我们的本地代码库根本就不知道有 C2 这个提交了。
注意: 在reset后, C2 所做的变更还在,但是处于未加入暂存区状态。
 
 
虽然在你的本地分支中使用 git reset 很方便,但是这种“改写历史”的方法对大家一起使用的远程分支是无效的哦!
为了撤销更改并分享给别人,我们需要使用 git revert。
git revert HEAD
使用指令前
使用后
奇怪!在我们要撤销的提交记录后面居然多了一个新提交!这是因为新提交记录 C2' 引入了更改 —— 这些更改刚好是用来撤销 C2 这个提交的。也就是说 C2' 的状态与 C1 是相同的。revert 之后就可以把你的更改推送到远程仓库与别人分享啦。
 
 

整理提交记录(git cherry-pick <提交号>...)

开发人员有时会说“我想要把这个提交放到这里, 那个提交放到刚才那个提交的后面”, 而接下来就讲的就是它的实现方式,非常清晰、灵活,还很生动。
本系列的第一个命令是 git cherry-pick, 命令形式为:
git cherry-pick <提交号>...
如果你想将一些提交复制到当前所在的位置(HEAD)下面的话, Cherry-pick 是最直接的方式了。我个人非常喜欢 cherry-pick,因为它特别简单。
咱们还是通过例子来看一下!
这里有一个仓库, 我们想将 side 分支上的工作复制到 master 分支,你立刻想到了之前学过的 rebase 了吧?但是咱们还是看看 cherry-pick 有什么本领吧。
输入git cherry-pick c2 c4
这就是了!我们只需要提交记录 C2 和 C4,所以 Git 就将被它们抓过来放到当前分支下了。 就是这么简单!
 

交互式的 rebase(复制记录)(git rebase -i )

当你知道你所需要的提交记录(并且还知道这些提交记录的哈希值)时, 用 cherry-pick 再好不过了 —— 没有比这更简单的方式了。
但是如果你不清楚你想要的提交记录的哈希值呢? 幸好 Git 帮你想到了这一点, 我们可以利用交互式的 rebase —— 如果你想从一系列的提交记录中找到想要的记录, 这就是最好的方法了
咱们具体来看一下……
交互式 rebase 指的是使用带参数 --interactive 的 rebase 命令, 简写为 -i
如果你在命令后增加了这个选项, Git 会打开一个 UI 界面并列出将要被复制到目标分支的备选提交记录,它还会显示每个提交记录的哈希值和提交说明,提交说明有助于你理解这个提交进行了哪些更改。
在实际使用时,所谓的 UI 窗口一般会在文本编辑器 —— 如 Vim —— 中打开一个文件。 
 
当 rebase UI界面打开时, 你能做3件事:
  • 调整提交记录的顺序(通过鼠标拖放来完成)
  • 删除你不想要的提交(通过切换 pick 的状态来完成,关闭就意味着你不想要这个提交记录)
  • 合并提交。 遗憾的是由于某种逻辑的原因,我们的课程不支持此功能,因此我不会详细介绍这个操作。简而言之,它允许你把多个提交记录合并成一个。
接下来咱们看个实例
开始的提交树
输入
git rebase -i HEAD~4
会弹出一个ui界面,获取到了HEAD上的4个父节点c2345
 
 
 
ui界面上的c2,c3,c4,c5对应着提交树上的c2,c3,c4,c5
接下来我们移动ui上的c2到c5,c3到c4
 
confirm
Git 严格按照你在对话框中指定的方式进行了复制。点击ui中的omit代表这个记录不会复制
 
 

Git Tags标签(git tag)

它们并不会随着新的提交而移动。你也不能检出到某个标签上面进行修改提交,它就像是提交树上的一个锚点,标识了某个特定的位置。
咱们先建立一个标签,指向提交记录 C1,表示这是我们 1.0 版本。
git tag v1 c1
很容易吧!我们将这个标签命名为 v1,并且明确地让它指向提交记录 C1,如果你不指定提交记录,Git 会用 HEAD 所指向的位置。
 

Git Describe(git describe)

由于标签在代码库中起着“锚点”的作用,Git 还为此专门设计了一个命令用来描述离你最近的锚点(也就是标签),它就是 git describe!
Git Describe 能帮你在提交历史中移动了多次以后找到方向;
git describe 的语法是:
git describe <ref>
<ref> 可以是任何能被 Git 识别成提交记录的引用,如果你没有指定的话,Git 会以你目前所检出的位置(HEAD)。
它输出的结果是这样的:
<tag>_<numCommits>_g<hash>
tag 表示的是离 ref 最近的标签, numCommits 是表示这个 ref 与 tag 相差有多少个提交记录, hash 表示的是你所给定的 ref 所表示的提交记录哈希值的前几位。
当 ref 提交记录上有某个标签时,则只输出标签名称
对于下面的提交树:
使用git tag v2 c3
git describe master 会输出:
v1_2_gC2  //离master最近的是v1标签与这个标签相差2个提交记录master的哈希值前几位是gc2
git describe side 会输出:    
v2_1_gC4
 

选择父提交记录

这里有一个合并提交记录。如果不加数字修改符直接检出 master^,会回到第一个父提交记录。
使用
git checkout master^
 
HEAD会回到第一个父提交记录
 
现在来试试选择另一个父提交……
git checkout master^2
HEAD会回到第二个父提交记录
 
 
克隆远程仓库(git clone)
直到现在, 教程都聚焦于本地仓库的操作(branch、merge、rebase 等等)。但我们现在需要学习远程仓库的操作 —— 我们需要一个配置这种环境的命令, 它就是 git clone。 从技术上来讲,git clone 命令在真实的环境下的作用是在本地创建一个远程仓库的拷贝(比如从 github.com)。 但在我们的教程中使用这个命令会有一些不同 —— 它会在远程创建一个你本地仓库的副本。显然这和真实命令的意思刚好相反,但是它帮咱们把本地仓库和远程仓库关联到了一起,在教程中就凑合着用吧。
先看看远程仓库(在图示中)的样子。
使用
git clone
就是它了! 现在我们有了一个自己项目的远程仓库。除了远程仓库使用虚线之外, 它们几乎没有什么差别
 

为什么有 o/?

你可能想问这些远程分支的前面的 o/ 是什么意思呢?好吧, 远程分支有一个命名规范 —— 它们的格式是:
<remote name>/<branch name>
因此,如果你看到一个名为 o/master 的分支,那么这个分支就叫 master,远程仓库的名称就是 o。
大多数的开发人员会将它们主要的远程仓库命名为 origin,并不是 o。这是因为当你用 git clone 某个仓库时,Git 已经帮你把远程仓库的名称设置为 origin 了
不过 origin 对于我们的 UI 来说太长了,因此不得不使用简写 o  但是要记住, 当你使用真正的 Git 时, 你的远程仓库默认为 origin!
如果检出远程分支会怎么样呢?
使用git checkout o/master; git commit
正如你所见,Git 变成了分离 HEAD 状态,当添加新的提交时 o/master 也不会更新。这是因为 o/master 只有在远程仓库中相应的分支更新了以后才会更新。
 
从远程仓库读取数据(Git Fetch)
这里我们有一个远程仓库, 它有两个我们本地仓库中没有的提交。
git fetch 
 
就是这样了! C2,C3 被下载到了本地仓库,同时远程分支 o/master 也被更新,反映到了这一变化
git fetch 并不会改变你本地仓库的状态。它不会更新你的 master 分支,也不会修改你磁盘上的文件。
理解这一点很重要,因为许多开发人员误以为执行了 git fetch 以后,他们本地仓库就与远程仓库同步了。它可能已经将进行这一操作所需的所有数据都下载了下来,但是并没有修改你本地的文件。我们在后面的课程中将会讲解能完成该操作的命令 
所以, 你可以将 git fetch 的理解为单纯的下载操作。
 
 
如何将远程数据保存到本地中( git pull
git pull
 
本地下载了远程数据并且远程c3和本地c2合并成了新的c4
 
fakeTeamwork 
fakeTeamwork 默认操作就是在远程仓库的 master 分支上做一次提交。
 
 
git fakeTeamwork
 
完成了 —— 远程仓库增加了一个新提交,我们还没有下载它,因为我们还没有执行 git fetch。
你还可以指定提交的分支或是数量,只需要在命令后加上它们就可以了。
git fakeTeamwork foo 3
 
 
 
上传本地仓库(git push)
这里我们准备了一些远程仓库中没有的提交记录
 
git push
过去了, 远程仓库接收了 C2,远程仓库中的 master 分支也被更新到指向 C2 了,我们的远程分支 (o/master) 也同样被更新了。所有的分支都同步了!
 
(更改)远程追踪
git checkout -b <新建分支名称>  <远程分支>
比如
git checkout -b totallyNotMaster o/master
 
就可以创建一个名为 totallyNotMaster 的分支,它跟踪远程分支 o/master。
第二种方法
git branch -u <被追踪分支名称> <远程分支名称>
这样<远程分支> 就会跟踪 <被追踪分支名称> 了。如果当前就在 <被追踪分支名称>上, 还可以省略 <被追踪分支名称>:
git branch -u<远程分支>
 

Git Push 的参数

git push origin foo:master意思是把远程的master同步到本地的foo,获取本地foo分支,上传给远程master
 
git push origin
git push origin master
把这个命令翻译过来就是:
切到本地仓库中的“master”分支,获取所有的提交,再到远程仓库“origin”中找到“master”分支,将远程仓库中没有的提交记录都添加上去,搞定之后告诉我。(将本地master上的分支提交到远程仓库,更新本地和远程仓库)
 
git push origin <place>
这个指令的意思是把本地的<place>更新到远程的<place>
 
你可能想问 —— 如果来源和去向分支的名称不同呢?比如你想把本地的 foo 分支推送到远程仓库中的 bar 分支。
要同时为源和目的地指定 <place> 的话,只需要用冒号 : 将二者连起来就可以了:
git push origin <source>:<destination>
git push origin foo^:master
 
把远程仓库里的master同步到foo的父级上
如果当你远程仓库没有master时,git会帮你在远程仓库自动创建
 
 
git fetch <place>
如果你像如下命令这样为 git fetch 设置 <place> 的话:
git fetch origin foo
Git 会到远程仓库的 foo 分支上,然后获取所有本地不存在的提交,放到本地的 o/foo 上。
git fetch也有 <source>:<destination>,不过 source 现在指的是远程仓库中的位置,而 <destination> 才是要放置提交的本地仓库的位置。它与 git push 刚好相反,这是可以讲的通的,因为我们在往相反的方向传送数据。
git fetch <远程仓库>  <本地仓库>
 
 
git pull origin <远程仓库>:<本地仓库>
用法和git fetch origin一样,不同点是从远程仓库下载节点后,会与HEAD(*)节点自动合并
 
 
 
 
posted @ 2020-11-26 22:31  听声是雨  阅读(241)  评论(0编辑  收藏  举报