Steins;Lab

某团的自留研究所

Git初阶使用笔记(1) - Start Up

不会用git的机械工程师不是好厨子(指炼丹与炒菜)。

 

1 前言

1.1 为什么使用git?

稍等,我把代码拷给你,你带U盘了吗?

Git是先进的分布式版本控制系统。

上图的文件组织方式你可能会很熟悉,这是单人进行写作时产生的遗留文件。时隔多日,我无法再回想起每次更新版本时做出的具体改动,但又不得不保留这些单文件。要我找出某一版本特有的内容,无异于上青天。

 

我们再把规模扩大,涉及到版本合并、分支控制。如果是10人规模的小型团队进行软件开发呢?再拓展到Linux内核的开发呢?

 

Git不只适用于代码版本控制,它适用于任何需要版本控制的场景。近年来Gitbook成为了博客或团队文档的选择。据笔者的道听途说,某传统企业的文档支持系统由原本的企业OA系统docx文档,迁移至自建Gitbook,效果良好。

 

先不说Git,代码管理是必备技能,这是过于真实的现实原因。

 

1.2 什么是git?

git是用于Linux内核开发的版本控制工具。与CVS、Subversion一类的集中式版本控制工具不同,它采用了分布式版本库的作法,不需要服务器端软件,就可以运作版本控制,使得源代码的发布和交流极其方便。git的速度很快,这对于诸如Linux内核这样的大项目来说自然很重要。git最为出色的是它的合并追踪(merge tracing)能力。[1]

 

git的许可协议是GNU通用公共许可证 第二版,GNU宽通用公共许可证 2.1版。

 

1.3 git简史

git是由林纳斯·托瓦兹(Linus Torvalds)发起。在linux内核经过手工合并的阶段后,Linus于2002年选择了一个商业的版本控制系统BitKeeper,由BitMover公司授权使用。BitKeeper是商业软件,这也一直在社区中引起质疑,因为这不清真这和自由软件的主旨相违背。直到2005年,BitKeeper的著作权者对安德鲁·垂鸠(Andrew Tridgell)对BitKeep的逆向工程不满,收回BitKepper的使用许可。

协商未果,Linus决定自行开发版本控制系统。十天时间后,完成了第一个git版本[2]。

此时,一位技术力爆表的暴躁老哥呼啸而过(图文无关)。[3]

 

1.4 GitHub

 

太长不看:GitHub是通过Git进行版本控制的软件源代码托管服务。

 

GitHub里面的项目可以通过标准的Git命令进行访问和操作。同时,所有的Git命令都可以用到GitHub项目上面。

网站提供了一系列社交网络具有的功能,例如赞(star)、关注(follow)、评论。用户可以通过复刻(fork)他人项目的形式参与开发,并可通过协作示意图来查看有多少开发者参与了开发并追踪最新的复刻版本。此外网站还有Wiki(通过一个名为 gollum 的软件实现)等功能。

GitHub同时允许注册用户和非注册用户在网页中浏览项目,也可以以ZIP格式打包下载。但是用户必须注册一个账号然后才能进行讨论、创建并编辑项目、参与他人的项目和代码审查。[4]

Github分为付费账户和免费账户。对于免费账户,能创建公开的代码仓库;付费账户在此基础上可以创建私有的代码仓库。之前我也有一篇文章记录了申请Student Developer pack的过程,赠送1年期的高级账户权限。

 

1.5 关于本文

本文是在博主使用实际中总结的笔记。着重点多在于git的使用上,忽略了git背后的原理和实现。而且直接将Github作为实验Playground,是一篇实用向的笔记。其中参考了许多精品的教程资料[5]。其中,官方文档和书籍形式的教程是非常好的资源,详见https://git-scm.com/book/zh/v2。

 

2 开始使用

2.1 连接至Github

git是是一个分布式的版本控制系统,是可以使用远程仓库的。在这篇笔记的实验中,我们直接连接至Github作为远程仓库。

值得注意的是,Github的开放仓库对所有人都是可见的。几天前华住集团住宿信息被脱裤,或因程序员将数据库连接方式暴露在公开仓库中[6]。

 

1 创建SSH Key

经常通过SSH管理VPS的同学可能对SSH Key非常熟悉。SSH秘钥可以让用户更加方便安全地登录到SSH服务器,无需输入密码。[7]

首先生成自己的SSH秘钥对

ssh-keygen -t rsa -C "youremail@example.com"

生成完毕后能看到主目录下的.ssh文件夹包含id_rsaid_rsa.pubid_rsa是“私钥”,绝对不能泄露。id_rsa.pub是公钥,是可以在公网放心泄漏的。

 

2 在Github上添加SSH Keys

3 git初始化

$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"

 

 

2.2 从GitHub新建库并克隆到本地

首先创建新的repository。

 

我起了个很俗的名字,就叫git-playground吧。

其中可以选择初始化README文件,然后选择许可证。许可证很重要,如果有志将项目发展下去,可以自己看下各开源许可的条款。

 

然后将库克隆到本地。

 

可以看到目录下拉下了刚才创建的库。

 

3 版本控制

3.1 提交更改

现在,我更改了工作目录下的README.md文件。

运行git status查看仓库状态:

 

 

可以用 git add 将文件添加至仓库。

初次克隆某个仓库的时候,工作目录中的所有文件都属于已跟踪文件,并处于未修改状态。[8]

 

git stauts可以看到仓库文件状态。若要比较文件,可以用git diff

 

提交到仓库:

git add README.md

git commit -m ""

git push

 

 

3.2 版本记录

我们先来对README.md进行多次修改和提交。

然后使用git log查看近三次提交。可以加上 --pertty=oneline

具体参数可以参见https://git-scm.com/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E6%9F%A5%E7%9C%8B%E6%8F%90%E4%BA%A4%E5%8E%86%E5%8F%B2

 

 

 

3.3 版本撤销/回退

若提交后发现有若干改动没有添加,可以使用--amend选项尝试重新提交

git commit --amend

最终这次提交会代替上次提交结果

 

版本回退:

git reset --hard HEAD^

其中,git reset用于回退版本。虽然在调用时加上 --hard 选项可以令 git reset 成为一个危险的命令(可能导致工作目录中所有当前进度丢失!)

HEAD可以理解为一个版本的指针。进行回退时,指针直接指向回退的版本。

^表示上一个版本。

可以用git reflog查看回退版本指针情况。

对于后悔药,为git reset --hard commit_id

 

这里摘抄一段穆雪峰老师的评论:

假设一开始你的本地和远程都是:

 

a -> b -> c

 

你想把HEAD回退到b,那么在本地就变成了:

 

a -> b

 

这个时候,如果没有远程库,你就接着怎么操作都行,比如:

 

a -> b -> d

 

但是在有远程库的情况下,你push会失败,因为远程库是 a->b->c,你的是 a->b->d

 

两种方案:

 

push的时候用–force,强制把远程库变成a -> b -> d,大部分公司严禁这么干,会被别人揍一顿

 

做一个反向操作,把自己本地变成a -> b -> c -> d,注意b和d文件快照内容一莫一样,但是commit id肯定不同,再push上去远程也会变成 a -> b -> c -> d

 

简单地说就是你无法容易地抹去远程库的提交信息,所以本地提交怎么都行,push前想好了

 

使用 git revert <commit_id>操作实现以退为进,

git revert 不同于 git reset  它不会擦除”回退”之后的 commit_id ,而是正常的当做一次”commit”,产生一次新的操作记录,所以可以push,不会让你再pull

 

 

 

实验记录

 

 

3.4 工作区与暂存区

实际我们进行正常更新文件的目录就可以看做我的工作区。而在工作区下有一个隐藏目录.git,是Git的版本库。

 

 

git中有个叫stage的暂存区,最开始时,还包含git自动创建的分支master,和指向master的指针HEAD

git add 是将文件修改添加到暂存区,git commit是将暂存区所有内容提交到当前分支。

 

值得指出的是,git追踪的文件的修改。如果做出以下操作:

第一次修改 -> git add -> 第二次修改 -> git commit

commit后提交的是第一次修改的结果,因为git add将第一次修改放入了暂存区域。

 

若要撤销更改,可以使用

git checkout -- [file]

使工作区的该文件撤回到最近一次 git commit或者git add的状态。

 

若要删除文件,可先rm掉文件,再使用git remove。若要恢复误删文件,可使用git checkout -- [file]

 

3 分支

分支是非常重要的功能!可以把分支理解成一个一个的开发线。在各自有自己功能的分支上或多人协作分支开发,最后合并,安全便捷。

举个不恰当的例子,就像下图一样,只不过各个分支可以根据项目需要在最后合并。

图: 底特律:便乘人 剧情分支图(不恰当的例子)

 

3.1 创建与合并分支

实际上HEAD指针指向的是master。在我们之前的常规提交,master分支不断向前,HEAD指针也随着向前进。

现在我们创建新的分支,用于开发,起名为dev。

git branch dev

git checkout dev

 

 

 

在dev分支上不断commit,HEAD指向dev

对于合并,最简单的的是将master指向dev。

Git鼓励大量使用分支:

 

查看分支:git branch

 

创建分支:git branch <name>

 

切换分支:git checkout <name>

 

创建+切换分支:git checkout -b <name>

 

合并某分支到当前分支:git merge <name>

 

删除分支:git branch -d <name>

 

将本地新创建的分支推送到github仓库。

git push origin dev

 

3.2 冲突解决

很容易想到,如果我们从master分支分出dev,那么devmaster都进行了新的commit,这样就需要我们解决冲突问题。

 

 

查看冲突:

 

 

 

看到了2个分支的冲突之处。

修改后使用git add该文件,可以提交。

之后的版本关系为

使用git log --graph

 

4 本文小结

本文是在博主使用实际中总结的笔记。着重点多在于git的使用上,忽略了git背后的原理和实现。

本文作为一个Start Up,暂时还不完整。

 

在下一期中,将补全以下内容

  • 实际环境中的使用技巧
  • 团队开发、多人协作注意点
  • 可视化
  • 在Visual Studio使用Git

 

 

参考资料

[1] git – Wikipedia https://zh.wikipedia.org/wiki/Git

[2] Git十岁了!Git之父Linus Torvalds说古,大谈Git开发秘辛 https://www.ithome.com.tw/news/95088

[3] https://linux.cn/article-640-1.html

[4] GitHub – Wikipedia https://zh.wikipedia.org/wiki/GitHub

[5] 廖雪峰的git教程 https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000

[6] 华住旗下酒店5亿信息疑被泄,专家:或因华住程序员失误所致 – 澎湃新闻 https://baijiahao.baidu.com/s?id=1610052563948067365&wfr=spider&for=pc

[7] SSH keys – ArchLinux Wiki https://wiki.archlinux.org/index.php/SSH_keys_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)

[8] Git-基础-记录每次更新到仓库 – git-scm https://git-scm.com/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E8%AE%B0%E5%BD%95%E6%AF%8F%E6%AC%A1%E6%9B%B4%E6%96%B0%E5%88%B0%E4%BB%93%E5%BA%93

1
说点什么

avatar
1 Comment threads
0 Thread replies
1 Followers
 
Most reacted comment
Hottest comment thread
1 Comment authors
youge Recent comment authors
  Subscribe  
最新 最旧 得票最多
提醒
youge
游客
youge

管他是什么先用起来再说系列