关于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

你可能感兴趣的:(关于GIT你所需要知道的一切)