关于GIT你所需要知道的一切

GIT简史


和Linus的Linux分不开,2002前,Linux居然是Linus本人亲自手工合并代码

2002-2005年,使用商业软件BitKeeper,授权Linux社区免费使用

2005年开发Linux Samba的Andrew 试图破解BitKeeper协议,被发现了,收回使用权

然后Linus花了两周用C写了一个分布式版本控制系统:git

2008年,github上线,git称为最流行的分布式版本控制系统

git词汇表(工作区,版本库,暂存区)


其他版本控制系统以文件变更列表的方式存储信息:存储的是差异积累,但是git不是

Git 更像是把数据看作是对小型文件系统的一组快照。 每次你提交更新,或在 Git 中保存项目状态时,它主要对当时的全部文件制作一个快照并保存这个快照的索引。 为了高效,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。 Git 对待数据更像是一个快照流。小型文件系统

git log中看到的hash是数据存储前作的校验和sha-1

branch:Git 的分支实质上仅是包含所指对象校验和(长度为 40 的 SHA-1 值字符串)的文件,所以它的创建和销毁都异常高效

git status -s:文件的状态

    已提交(已经保存在本地版本库 git commit)---> 本地版本库 repository(.git directory

    已暂存(git add)--->暂存区staging area

    已修改(已经修改,但是还没有add)--->工作区working directory

    未跟踪 untracked :之前的快照中不包含这些文件--->工作区working directory

被忽略的基本操作(diff, mv, rm)


git diff:

    不加参数只显示尚未暂存的改动,而不是自上次提交以来所做的所有改动,一般是git status 和git add之间使用

    --staged/--cached:查看已暂存的将要添加到下次提交里的内容

git commit:

    -a(跳过暂存区) 

    -m(直接写message的subject信息)

git rm:

    git rm xxx = rm xxx && git add

    如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项-f

    让文件保留在磁盘,但不让 Git 继续跟踪,使用--cached选项(把本应忽略的文件提交的时候)

    支持模式匹配

git mv:

    git mv A B = mv A B & git rm A & git add B

自定义(别名, .gitignore)


alias:

    git config --global alias.co checkout

    git config --global alias.unstage 'reset HEAD --'

    git config --global alias.last 'log -1 HEAD’

    git config --global alias.visual '!gitk'

.gitignore:

    无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表

    所有空行或者以 # 开头的行都会被 Git 忽略。

    可以使用标准的 glob 模式匹配(shell 所使用的简化了的正则表达式)

星号(*)匹配零个或多个任意字符;

[abc]匹配任何一个列在方括号中的字符

问号(?)只匹配一个任意字符;

方括号中使用短划线分隔两个字符(比如[0-9]表示匹配所有 0 到 9 的数字)。

使用两个星号(*) 表示匹配任意中间目录,比如`a/**/z` 可以匹配a/z,a/b/z或 `a/b/c/z`等

匹配模式可以以(/)开头防止递归。

匹配模式可以以(/)结尾指定目录。

要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。

代码回退(reset, revert, checkout)


git commit —amend:

    一着急提交信息写错了/漏提交文件了: 最后只有一次提交

git reset:

    不小心 git add了和本次commit无关的东西: git reset HEAD file_name   (--mixed是默认参数)

    如果你在引用的尾部加上一个^, Git 会将其解析为该引用的上一个提交:HEAD^:“HEAD 的父提交”

    merge 解决冲突时,搞花了,git reset --hard HEAD

    3个参数:

--soft:撤销了上一次git commit命令

--mixed:撤销一上次提交,但还会取消暂存所有的东西。 于是,我们回滚到了所有git add和git commit的命令执行之前

--hard:你撤销了最后的提交、git add和git commit命令以及工作目录中的所有工作

git checkout (discard)

    改花了,不想要了,还原成本地版本库的样子):git checkout — file_name

    reset会移动 HEAD 分支的指向,而checkout则移动 HEAD 自身

git revert:

git revert -m 1parent

多人协作(fetch, pull, push, blame, 冲突)


pull:

    =fetch+merge

commit message的一些约定:

如何编写commit message: https://chris.beams.io/posts/git-commit/

git emoji约定:https://gitmoji.carloscuesta.me/

git push:

    不带参数会默认push 到 origin branch_name, 但是不管tag

冲突:

    both modified

    解决冲突,add,再commit

    默认的commit信息中会告诉你冲突文件是什么

git log:

git log --left-right master…experiment:选择出被两个引用中的一个包含但又不被两者同时包含的提交

git stash:

    切分支前,暂存还不想提交的代码

git stash

git stash list

git stash apply

cherry-pick:

假设我们有个稳定版本的分支,叫v2.0,另外还有个开发版本的分支v3.0,我们不能直接把两个分支合并,这样会导致稳定版本混乱,但是又想增加一个v3.0中的功能到v2.0中,这里就可以使用cherry-pick

操纵历史( rebase)


rebase:实质是丢弃一些现有的提交,然后相应地新建一些内容一样但实际上不同的提交

rebase的含义:

    把你的commit一个接一个的重现在某个分支的顶端

    保持你的commits的顺序

不要对在你的仓库外有副本的分支执行rebase

否则,人民群众会仇恨你,你的朋友和家人也会嘲笑你,唾弃你

一个基于rebase的workflow--atlassian

这个模型基于rebase的第二种含义

过程:

基于master拉分支

开发过程中,如果master有变化,重复:

    git fetch origin

    git rebase origin/master

如果多人合作,重复:

    git fetch origin

    git rebase origin/branch

上面两个过程可能有conflicts,rebase的冲突是一个一个出来的

git push

当pull request 被approved

    git rebase -i origin/master

此时push,可能会需要-force,因为在改变public branch的历史

最后merge到master:

    git checkout master

    git pull

    git merge --no-ff branch

这些配置,让上面的过程更顺畅:

git config --global branch.autosetuprebase always

git config --global pull.rebase preserve #(this is a very recent and useful addition that appeared in git 1.8.5)

git workflows 


git flow第一批模型:

    核心是master 分支和develop分支,这两个分支的生命周期是永远

    master分支永远是可部署到生产环境的状态,develop是下一个准发布版本

    当develop分支OK了,可以发布了,merge 回master,在master上打上release tag

    支持性分支(这里所有的分支分类都只是约定的使用规范):

    feature/topic分支(主要用于不确定发布时间或者不确定最后会不会被采纳的新特性)

        一般从develop开分支,OK后,merge回develop分支

        merge回develop使用—no-ff 参数

        需要注意的是这里的feature branch不会出现在origin里,也就是不会push到origin/feature branch

    release分支

        用来支持下次发布的分支,也是从develop拉分支

        merge回master,给master打tag

        merge回develop(这两部也建议使用—no-ff参数)

        删除release分支

    hotfix分支

        一般从master拉分支,解决生产环境的严重bug(必须立即修复的那种)

        merge回master,给master打tag

        merge回develop(这两部也建议使用—no-ff参数);如果此时有release分支,可以merge回release分支来代替

        删除release分支

github flow:

轻量,非常简洁,适合有持续集成每天多次部署的团队

基于master开分支(branch)

在分支上完成开发

开pull request,并基于PR进行code review

    pull request可以在开分支的初期就开,便于和其他人进行初期构想的讨论

    在分支上的提交会自动更新在pull request上

部署分支到生产环境

验证分支是否OK

    如果不OK,使用master重现部署生产环境

    如果OK,merge master,删除分支

核心:master上的代码始终是可部署的,这里的可部署是指已经实际在生产环境验证过了

gitlab workflows:

    production branch:app发布或者有发布window时,每次merge master 并不意味着现在master就能部署

production branch代表了生产环境代码,每次实际上线,将master merge到production branch,然后上线

    env branches:

a staging environment:master代码

a pre-production environment:开master和pre-production branch 的merge request,

a production environment:从把pre-production merge到production branch

    release branches:

从master拉release分支

'upstream first’policy:bug修复先merge到master,然后再cherry-pick到release branch

pull request vs. merge request:

pull request: github等,第一个动作是pull feature branch

merge request: gitlab, 最后一个动作是merge

都可以在branch开始后就开(WIP时可以不分配给任何人)

pull request/merge request merge的时候:

创建一个merge commit

默认使用--no-ff 参数

在descritption里写issue number可以关联并在merge后自动关闭对应的issue

扩展阅读


    PRO GIT BOOK 2nd Edition:(有中文版)

        https://git-scm.com/book/zh/v2

    .gitignore:

        https://github.com/github/gitignore

    How to Write a Git Commit Message:

        https://chris.beams.io/posts/git-commit/

        https://gitmoji.carloscuesta.me/

    workflows and branching models and strategies:

        A Successful Git branching model:http://nvie.com/posts/a-successful-git-branching-model/

        Github workflow:https://help.github.com/articles/what-is-a-good-git-workflow/

        atlassian:https://www.atlassian.com/blog/archives/simple-git-workflow-simple

        gitlab:https://docs.gitlab.com/ee/workflow/gitlab_flow.html

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,219评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,363评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,933评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,020评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,400评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,640评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,896评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,597评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,327评论 1 244
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,581评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,072评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,399评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,054评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,849评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,672评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,585评论 2 270

推荐阅读更多精彩内容