最近工作比较多用到git,之前只有较为粗浅的认识,虽然执行了一条命令看到console在跑,但对git的总体工作流,命令特性上的异同和数据结构等并没有较深入的了解。
像我们常用的开发工具IDEA,已经帮我们在代码管理上做了很多额外的工作。如果开发在平时的编码过程中,对自己提交代码的过程不注意,开发之间的任务分工互相没有重叠,开发的过程没有遵循一般的版本控制流程的话,再久也不会了解Git的操作流程与原理。
所以在这里我会列一些概念与本人的一些实践给大家做参考。
简述
Git是一个分布式版本控制工具,你可以通过他的诸多命令,通过Git本身支持的多种协议(git/http/https)获取(pull/fetch)远端的拷贝代码。
Git仓库可通过git init
命令初始化整个工作目录,生成.git
文件夹,该文件夹下保存放着Git完整的数据结构,
.git/
├── branches
├── config
├── description
├── HEAD
├── hooks
├── info
│└── exclude
├── objects
│ ├── info
│ └── pack
└── refs
├── heads
└── tags
它通过版本(revision)、提交(commit sha-1)、树(tree)、blob对象来构成整个提交记录,每个版本指向一次提交,提交指向树,树指向多个blob对象,树只保存引用,如果文件无修改,会保存引用为上次提交的blob数据。
Git对于被操作的文件有差异化校验(diff),如果版本库(.git)下的文件被修改,工具会直接将变更状态(new/modify/delete)显示在工作空间中,而工作空间只是区域中的一种,实际包括工作空间(working tree)、暂存区(staging area)、仓库(repository),文件分别通过git add
与git commit
将自身移动到下一个区域,也可以通过git rm
来移除版本跟踪。
官网介绍
Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.
Git is easy to learn and has a tiny footprint with lightning fast performance. It outclasses SCM tools like Subversion, CVS, Perforce, and ClearCase with features like cheap local branching, convenient staging areas, and multiple workflows.
上边这段的大致翻译是:Git快速而又高效,解决小型直至超大型项目的版本控制问题,并且是免费、开源的。Git易学、轻量、速度快,它诸多特性,如:轻量的本地分支、便捷的暂存区、复杂的工作流使其优于其他SCM工具,如:subversion、cvs、perforce、clearcase等
如果还有兴趣继续了解,可以看附录:官网 了解更多。
基本术语
- WORKING COPY/WORKING TREE:工作空间,git init的地方,修改未暂存未提交的都在这里
- staging area:暂存区,执行了git add的区域
- repository:仓库,git commit的都在这里
- HEAD:当前操作指向的版本
- revision:版本,git commit之后生成的SHA-1哈希值所代表的某次提交引用
- INDEX:索引,暂存区即将提交的文件集合
- 文件的生命周期基本为:工作空间–git add–>暂存区–git commit–>仓库
简单命令
命令 | 简述 | 效果 | 示例 |
---|---|---|---|
git init | 初始化仓库 | 当前目录下产生.git 目录 | git init |
git clone | 克隆远程仓库 | 拉取远程仓库并在当前目录新建一个新目录作为仓库 | git clone https://github.com/mesosphere/RENDLER.git |
git add | 文件加入暂存区 | 从untrack->new file | git add filename |
git mv | 移动文件 | 状态变为rename | git mv aa bb |
git reset | 回退到某一版本 | 有多种模式keep/soft/hard/mixed/merge任君选用 | git reset revision-id |
git rm | 移除跟踪文件 | 从track->untrack,如果在暂存区,直接删除文件或回退到当前未修改版本 | git rm filename |
git log | 查看提交日志 | 很多花样 | git log |
git show | 查看文件修改细节 | 同上 | git show filename |
git status | 查看当前仓库状态 | 比如modify/new file/untrack/deleted等 | git status |
git branch | 跟分支有关 | 对分支的操作 | git branch |
git checkout | 检出本地仓库的某个分支 | 同上 | git checkout master |
git commit | 将文件从暂存区提交到本地版本库 | 同上 | git commit -m ‘commit something’ |
git diff | 查看版本的区别 | 同上 | git diff revision1 revision2 |
git merge | 两个分支合并 | 同上 | git merge master child |
git rebase | 两个分支或者多个提交合并为1~n个提交 | 同上 | git rebase master child/git rebase -i revision |
git tag | 给版本打标签 | 同上 | git tag tag1 |
git fetch | 拉取远端仓库,不自动合并 | 同上 | git fetch |
git pull | 拉取远端仓库并通过策略合并 | 拉取到本地 | git pull |
git push | 推送到远端仓库 | git push | |
git reflog | 查看所有过往操作日志 | 跟mysql的binlog一样 | git reflog |
常用命令
命令 | 效果 |
---|---|
git log | 查看当前分支的提交历史 |
git log – [filename] | 查看某一文件的提交历史 |
git log -pretty=oneline – [filename] | 某一文件的提交历史,只显示精简一行,revision+message |
git status | 查看当前working tree与staging的状态 |
git commit --all -m ‘[msg]’ | 从staging暂存区中提交到本地仓库 |
git add --all | 将所有操作过的文件一并添加到暂存区中 |
git rebase -i [revision] | 交互模式进行衍合操作,交互interactive中有多个命令在[1]中查看 |
git rebase master | 如当前branch为test-branch,可以执行衍合,分支上的提交会合并到master上,并且提交数一致,比较整洁,不会出现Merge的额外提交,如果有冲突解决冲突完执行git rebase --continue处理,git checkout master后执行git merge test-branch后,git会执行Fast-forward直接将HEAD移动到最新提交上 |
git merge test-branch | 当前分支master,test-branch分支由master分出,执行命令后,将test-branch合并到master,在master生成一个新提交 |
git show [filename] | 查看文件提交历史 |
git checkout test-branch | 切换到test-branch分支 |
git branch test-branch | 基于当前分支创建一个新分支,名为test-branch |
git branch | 当前HEAD指向的分支 |
git rebase --continue --abort | 解决了冲突或者执行了其他操作,继续执行衍合,或终止衍合操作 |
git diff [revision] | 查看当前版本与某一个版本的区别 |
git reset [revision] --soft --hard --mixed --keep --merge | 重置指令,将仓库/暂存区/工作树基于某一版本回退,具体命令参见[2] |
git mv [from] [to] | 修改某一文件名 |
git rm [filename] | 有commit无修改,则直接移除文件,并添加到暂存区为deleted状态 |
git rm --cached [filename] | 有无commit有add,则移除暂存区 |
git stash save ‘[msg]’ | 保存某一时刻的快照,并回退到当前未修改版本,添加描述信息 |
git stash | 保存某一时刻的快照,stack模式,放到头部 |
git stash list | 查看快照列表 |
git stash pop/apply [topic] | pop释放并删除/apply不删除某一个快照到当前版本,apply需解决冲突后drop,pop会显示冲突 |
git tag [tag] | 打标签 |
git commit --amend --no-edit | 补丁提交到上当前版本,版本被修改,message不变 |
git tag [tag] | 打标签 |
git commit -m [msg] – [filename] | 提交暂存区某个文件到本地仓库 |
git push -f | 强制提交当前版本到远端仓库 |
备注
[1]衍合交互模式操作
- p, pick = use commit 基于什么提交
- r, reword = use commit, but edit the commit message 提交,修改提交信息
- e, edit = use commit, but stop for amending 提交,提交前修改,比如可以继续commit,执行git rebase --continue才执行完毕
- s, squash = use commit, but meld into previous commit 合并多个提交为一个提交
- f, fixup = like “squash”, but discard this commit’s log message 合并多个提交为一个提交,并忽略之前的提交信息
- x, exec = run command (the rest of the line) using shell 这个不懂
[2]重置(可参考:https://www.yiibai.com/git/git_reset.html),这里用缩写,working tree(wr),staging area(sa),repository(r),!wr解释为工作空间未修改,wr为修改 - soft !wr,!sa,r
- hard wr,sa,r,可以通过git reflog找回历史重置
- mixed 默认 !wr,sa,r
- keep 略
- merge 略
其他
- 版本树显示命令:git log --graph --all --pretty=format:’%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset’ --abbrev-commit --date=relative
附录
私有云
- gitlab:最完备的基于git的CI工具
- gogs:专注于scm工具
公有云
- github:全球最著名的开源代码托管平台
- bitbucket:适用于小团队的代码托管平台
- gitee:码云,开源中国旗下的开源代码托管平台
- coding:扣钉,国内知名集代码托管与项目管理平台
电子书
参考
- BitKeeper与Linux,git史前琐事:https://blog.csdn.net/glory1234work2115/article/details/51277402
- git安装:https://git-scm.com/book/zh/v2/起步-安装-Git
- 官网git-scm:https://git-scm.com
- 廖雪峰git教程(入门):https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000
- 你应该知道的git高级技巧:https://www.cnblogs.com/oyx305/p/5935984.html