学习Git,看这一篇文章就够了

git book 中文版链接:http://gitbook.liuhui998.com/index.html
最近公司需要每个人准备一次培训,我是做客制案的,可能我讲luancher,Settings这些应用对驱动或者硬件的同事来说并没有多大的用处,如果每个人都能用到的,那非git无疑了。作为一个git使用并不长的开发者来说,我平时遇到了很多问题,常常不得不去百度或者请教其他同事,这里也做一个系统的整理,希望各位读者能够今后更好的使用git。
<一、git是什么>
这里写图片描述
Git是一个开源的分布式版本控制系统,可以有效、高速的处理从很小到非常大的项目版本管理, 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。相对于SVN的集中式版本控制工具,GIT可以在本地进行代码修改,然后在联网的时候进行代码上传,就算服务器发生故障也不会影响本地的工作。

<二、git工作目录>
这里写图片描述

GIT的工作目录可以分为3种:远程服务器上的代码仓库、本地代码仓库,本地工作区。
本地工作区里代码的状态也可以分为三种:untracked、modified(index暂存区)、commited。

在我们平时做客制化的订单的时候每个人有一个自己的本地开发分支。

这里写图片描述
.git是git目录,默认是隐藏的。我们可以看到他有这些文件,那么这些文件的用处是什么呢?
我们可以在终端里输入下面的命令:git help gitrepository-layout
然后会有详细的说明文档。

  • HEAD //表示这个git项目处在哪个分支里
  • config //项目的配置信息,输入git config相关命令将会改动它
  • description //被gitweb (Github的原型)用来显示对repo的描述。
  • hooks //Git有一套可以自动运行在任何一个有意义的git阶段下的脚本,叫做hooks。hooks可以运行在commit/rebase/pull等等状态的之前或之后。脚本的名称决定了它什么时候被执行。一个有用的pre-push脚本的例子将会被运行以测试控制器(远程控制)中的所有样式规则保持一致。
  • index //索引文件
  • logs //各个refs的历史信息
  • objects // 本地仓库的所有对象 (commits, trees, blobs, tags)
  • refs //项目里的每个分支指向了哪个commit
    其他文件可以在说明文档里看详细的说明。

HEAD文件
.git/HEAD 目录下的HEAD文件是直接指向当前分支的,在我的.git目录下打开这个文件可以看到里面的内容是:
ref: refs/heads/hq_si7537sc_EX710
我们通过这个引用路径去查看,发现对应的hq_si7537sc_EX710文件打开是一串哈希值:81ecd8fc36eb51ba91ce013f25300733407fa73f
我们用git show 81ecd8fc36eb51ba91ce013f25300733407fa73f 或者git log命令可以发现这串哈希码对应的是hq_si7537sc_EX710 。这个分支的最新提交。因此我们可以得出结论:HEAD直接指向当前的分支,间接指向当前分支的最新提交。

refs文件夹
index文件
git中的索引(index)是一个存放了排好序的路径的二进制文件(通常是.git/index), 每一个条目都附带有一个块对象的SHA1值以及访问权限; 我们可以通过

git ls-files --stage

来显示它。例如他的部分内容是这样:

120000 45046a088a3b6c3ab45eadb7fede7e1b3760f172 0   prebuilts/ndk/6/platforms/android-4/arch-arm/usr/include/linux/if_tun.h
120000 3b1729b500730994e54c1b70bac80af4daa00751 0   prebuilts/ndk/6/platforms/android-4/arch-arm/usr/include/linux/if_vlan.h
120000 2ed08ace8ccb860516665022e084a5454ecb8967 0   prebuilts/ndk/6/platforms/android-4/arch-arm/usr/include/linux/in.h
120000 fdf47335103cd4c50b59f0a51efd5072347349ee 0   prebuilts/ndk/6/platforms/android-4/arch-arm/usr/include/linux/in6.h

·请注意, 在一些旧的文档中, 索引可能被称为”当前目录缓存(current directory cache)”或者”缓存(cache)”.
索引(index)有三个重要的属性:
1、索引存储了生成一个(独一无二的)树对象所需要的所有信息.
例如, 运行git commit会从索引中生成一个树对象, 把这个树对象存储在对象数据库(object database)中, 然后把它与这个提交关联起来. (译注: 回忆”查看Git对象”一章, 每一个提交都对应一个树对象.)
2、索引使得对索引生成的树对象和工作树进行快速比较成为可能.
索引通过存储每个对象的一些额外信息(比如说最后修改时间)来完成这个工作. 这些数据没有在上面显示出来, 也没有存储在创建出来的树对象中, 但是它们可以用于快速找出当时工作目录中的文件与索引的差异, 从而让Git不必将文件的内容全部读出.
3、索引可以有效地表示树对象合并时的冲突信息, 使得每一个路径名都有足够的信息与树对象联系起来, 从而可以对它们进行三路合并.
在合并期间, 索引可能存储一个文件的多个版本(称为”stages”). 上面git ls-files的第三栏输出就是stage号. 在出现合并冲突时, 这个号码会是其他值, 而不是0.
因此索引实际上是一种暂存区域(temporary staging area), 它装载了你正在使用的树对象.

这里写图片描述

git fetch 和git clone 区别
git rm 和 rm
git checkout -b和git checkout

git remote 查看现有的远程仓库列表
git fetch 将远程仓库数据抓取到本地
git clone 会为它被克隆的远程repo创建一个名为“origin”的local repo,并为远程repo的活动分支创建一个本地分支master以及远程跟踪分支。

分支关联
git branch –set-upstream origin/debug 分支关联
git branch –set-upstream [branch-name] [origin/branch-name]
可以将某个远程分支设置为本地分支的“上游”。
在版本教新的Git中,该命令已经不推荐使用,而是使用“–track”参数或“–set-upstream-to”参数。
创建本地分支并追踪远程某个分支,可以用一个命令搞定:
git branch –track local_branchname origin/remote_branchname
手动设置本地分支的上游时,推荐使用命令:
git branch –set-upstream-to=origin/ remote_branchname
取消对某个分支的跟踪,使用命令:
git branch –unset-upstream local_branchname

检查冲突

当发生冲突时,Git会将冲突的部分标记出来

$ cat hello
hello
<<< HEAD
worlds
= = = =
world

Yay!
其中<<<<<<<这一行和=======这一行之间的部分是来自目标分支的, 而=======和>>>>>>>直接的内容是来自于要合并的分支的。

git rebase test
这个时候,git做了些什么呢?

先将test分支的代码checkout出来,作为工作目录
然后将master分支从test分支创建起的所有改变的补丁,依次打上。如果打补丁的过程没问题,rebase就搞定了
如果打补丁的时候出现了问题,就会提示你处理冲突。处理好了,可以运行git rebase –continue继续直到完成
如果你不想处理,你还是有两个选择,一个是放弃rebase过程(运行git rebase –abort),另一个是直接用test分支的取代当前分支的(git rebase –skip)。

git rebase 和git merge的区别

这里写图片描述

如图假如在远程 remotes/origin/ master 分支的C节点上git checkout -b 出一个新的本地local分支继续在本地开发,与此同时又有人往master分支上提交新的内容,这个时候master分支指向最新的一次提交(D节点)。而在本地分支上陆续有新的提交,local分支指向最新的一次提交(G节点)。从图中可以当前分支是位于local分支上(HEAD指向)。现在你的本地开发要把D节点的提交内容合并到local分支上,这个时候就涉及到分支合并了。
使用合并分支操作的时候都可以用git rebase 和git merge操作来实现,但两者有什么区别呢?

这里写图片描述
git rebase 合并分支步骤:

git checkout local
git rebase master

1、用git status -s 确保所有本地修改都被提交了
2、git rebase <当前分支> <合并的目标分支>,发生冲突手动解决冲突后再git add 然后git rebase --continue。如果想要撤销本次rebase可以使用git abort

使用git rebase后会将master分支新的提交作为一个副本重新提交到local分支。注意并不是复制,大家可以看留心看下合并前后两个相同的提交他们的hashcode并不一样。

注意:千万不要在公共分支(比如master)上进行合并分支操作。如果这样做,会造成master分支移动指向最新的提交,这样其他人在master上的修改提交都会有冲突发生,非常的麻烦

使用git merge合并master分支到local分支上:

git checkout local
git merge master

或者直接 git merge master local

git merge的结果如图,它会将合并后解决的冲突的内容形成一个新的提交记录H节点。如果从master分支上checkout出新的分支local后master上没有新的提交,此时将master 分支合并到local上会直接向前合并(fast-forward merge),这个时候没有冲突时依然会产生一个新的提交。如果你不想要这个提交可以使用git merge –no-ff

总结:git merge 和git rebase的差别:
1、git merge 解决冲突后只会有一个commit 提交,git rebase会将合并分支的提交作为一个副本拿过,这样看上去有多个提交
2、git rebase 的是线性历史提交树,git merge是交错的提交

远程分支
git push origin local:origin/remote/local 将本地的local分支推送到远程仓库
git push origin :origin/remote/local 将远程仓库中的local分支删除

查看远程分支的状态:

git remote show origin

如果本地追踪远程分支:

git branch --track myfeature origin/myfeature  
git checkout myfeature

如果你想根据指定的作者查找:

$ git log –author=Andy
更新:感谢 Johannes的评论,解除了我的一些困惑,

或者你可以搜索你提交信息的内容:

$ git log –grep=”Something in the message”
这些强大的指令被称为pickaxe指令,来检查被移除或添加特定块的内容(比如,当他们第一次出现或者被移除),添加任何一行内容都会告诉你(但是并不包括那行内容刚刚被改动)

$ git log -S “TODO: Check for admin status”
如果你改动一个特定的文件会怎么样?如:lib/foo.rb

$ git log lib/foo.rb
如果你有feature/132 和ferature/145这两个分支,并想查看这些不在master上的分支内容。( ^ 符号是意味着非)

$ git log feature/132 feature/145 ^master
你同样可以使用ActiveSupport风格的日期来缩短时间范围:

$ git log –since=2.months.ago –until=1.day.ago
默认会使用OR来合并查询,但你也可改用AND(如果你有不止一个条件)

$ git log –since=2.months.ago –until=1.day.ago –author=andy -S “something” –all-match

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mrsongs的心情杂货铺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值