Git工作原理

存储格式

Git记录的是文件所有版本的快照,而非是版本间的差异,因此Git版本切换的速度会很快。
且Git在存储数据前,会对文件内容作校验和计算,通过SHA-1散列算法,因此可以检测出文件中修改的信息。此外,Git并不是通过文件名来标记数据,而是通过散列值。

文件状态

目录下的文件可分为tracked(已跟踪)和untracked(未跟踪)两种状态。
tracked:指处于Git控制下的文件,可以进行暂存、提交等操作;
untracked:指会被Git系统忽略的文件,此外也可通过配置.gitignore文件来设置忽略哪些文件。

tracked文件的状态

首先引入Git系统的三个区域:Git仓库、工作目录和暂存区
Git系统的三个区域
根据这三个区域,tracked文件可分为三种状态:staged(已暂存)、committed(已提交)、modified(已修改)。
staged:指已存入暂存区的文件,下次提交时会将暂存区中的文件提交到Git仓库。
committed:指已经提交到Git仓库中的文件,也可理解为未修改的文件。
modified:表示已修改,但还未提交到仓库中的文件。
文件状态周期

使用Git

Linux下:安装Git后,就可以通过命令行执行git指令了
Windows下:安装Git后,可通过Git Bash(命令行)和Git GUI(图形界面)两种方式使用。
注:目前IDE大多集成了Git的功能,直接在IDE里点一点就可以很方便地使用Git。但为了充分了解Git的工作方式和原理,还是需要学习一下Git的相关指令。

Git Bash

  • Shell
    Shell字面理解是“壳程序”(操作系统可以分为核心kernel和外壳Shell两部分),用于用户和内核间的交互。相当于是一个命令解析器,其接收用户命令,然后调用相应的应用程序,完成相应的功能。
    Shell有很多种,如Bourne SHell(sh)、Bourne Again SHell(bash)、C SHell(csh)等,这些Shell最大的区别就是命令集的不同。
    注1:在linux中预设的Shell就是bash;在Windows中的Shell是cmd和PowerShell,cmd功能较为简单,PowerShell功能则非常强大,可以看作cmd的超集。
    注2:如何区分各种shell?可通过命令的开头字符,如果是$, #则为bash($为普通用户,#为管理root超级用户),如果是PS <当前地址>则为Powershell,如果直接是<当前地址>则为cmd。
    PowerShell
    注3:同时Shell又是一种编程语言,可自动执行一连串的命令,并具有定义变量、循环/分支控制结构等特性。

  • Git Bash
    Git Bash是Git在Windows下模拟的Linux命令行环境,在这个环境下可以使用Git命令、常用的Linux命令等。

  • 在Git Bash中复制粘贴
    可以直接右键,也可以用快捷键:(但不能ctrl+c/v)
    复制:ctrl+ins
    粘贴:shift+ins

Git基础命令

常用linux命令

mkdir xxx:创建空目录(在当前目录下)
cd xxx:转移到新路径
pwd:显示当前目录
ls:查看文件夹包含哪些文件

Git初始化设置

必要的两个初始化配置:姓名和邮箱
git config --global user.name "<name>":设置姓名
git config --global user.email "<email>":设置邮箱
git config --list:查看设置

创建版本库

git init:将当前目录变为git可管理的仓库

查看文件状态

git status:查看工作区中的文件状态(是否有文件被修改过)
git diff:查看文件具体的修改内容(默认是比较版本库中和工作目录中的文件)

提交文件

git add <文件名>:这是一个多功能命令,既可以用来跟踪新文件(tracked),也可用来将文件添加到暂存区,可将其理解为“添加内容到下一次提交中”。
git commit -m "<提交说明>":将暂存区中的文件提交到仓库。
git commit -a -m "<提交说明>":直接将文件提交到仓库(跳过暂存区)。

从跟踪列表中移除文件

git rm --cached <文件名>:将某文件从跟踪列表中移除,但硬盘上还会保留,只是不再跟踪。
另一种方法:设置.gitignore文件,遵循glob模式(shell所使用的简化了的正则表达式格式)
规则:
/:以/开始为禁止递归匹配(只在当前目录下匹配),以/结尾表示目录
*匹配任意个字符;
[]匹配括号内任意单个字符;
[0-9]使用短划线匹配一段范围内的字符,这个例子中是匹配0到9之间的任意数字;
?匹配任意单个字符。
#:注释
eg:
*.a:忽略.a类型的文件
/TODO:只忽略当前目录下的TODO文件,而不忽略子目录下的TODO文件
/build:忽略build目录下的所有文件
常用的.gitignore模板

删除文件

在工作区中删除文件后
确实要删除:git rm <文件名>git commit -m xxx,删除版本库中的文件。
删错了:git checkout -- <文件名>,恢复文件。

查看提交历史

git log:查看commit历史记录(按q退出),只有当前版本之前的信息。
git log --pretty=oneline:简略显示,在每一行显示一个提交,只包含提交说明。
git reflog:简略显示所有的提交信息。

撤销操作

git checkout -- <文件名>:撤销工作区中文件的修改,用仓库中上一个版本的文件覆盖。
git reset HEAD <文件名>:撤销提交到暂存区的文件。
git commit --amend:提交后发现提交错了(写错提交说明,文件没修改完全等),使用此命令覆盖提交到仓库的上一个版本。原理:重新提交暂存区中的文件,因此如果暂存区没有更改,则仓库中的文件也不会更改。
git commit --amend -m "<新的提交说明>":更改上一次提交的说明信息。
git reset --hard HEAD~<n>:版本回退,HEAD为当前版本,n代表向前回退几个版本,或者HEAD~10代表往上10个。或者git reset –hard xxx(版本号的前几位即可)。

远程仓库的使用

git remote:查看远程仓库,origin为克隆源服务器的简称;-v参数:显示url地址。
git push origin <要同步的分支名>:推送到远程库
git clone git@github.com:lrStyle/xxx.git(文件名):从远程库克隆
注:上述操作都可用IDE集成的git来完成,不用专门输命令。
追踪分支:当clone项目时,系统会自动使本地的master分支跟踪origin/master分支,因此就可以直接pull/push而不用显示指明本地分支和远程分支名。
使用IDE集成的git控制:开始工作前先同步,推送前先同步,保证你向远程库推送的修改不会与别人冲突。

  • 分支操作
    查看分支:git branch
    创建分支:git branch xxx(分支名)
    切换分支:git checkout xxx(分支名)
    创建+切换分支:git checkout -b xxx(分支名)
    合并某分支到当前分支:git merge xxx(要合并的分支名)
    删除分支:git branch -d xxx(分支名)
    强制删除未合并的分支 :git branch -D xxx(分支名)
    若合并分支时存在冲突,需要手动解决冲突再提交。
    git log –graph :查看分支合并图

VS集成Git工具的使用

更改:相当于提交commit,将修改提交到本地库
同步:先将远程库拉取,再将本地库推送到远程库,相当于(Pull+Push)
推送:将所做的更改,存入远程版本库
提取(Fetch):从远程版本库获得最新版本
拉取(Pull):将远程版本库合并到本地版本库,相当于(Fetch+Merge)
变基到(Switch):切换分支(双击即可切换)
VS中Git小图标
VS右下角会有两个Git小图标,如上图所示。
铅笔:commit;右边的数字:发生修改但还未commit的文件数。
上箭头:点击后会跳到同步界面,这时可点击“推送”将更改推送到远程库;右边数字:commit了但还未Push的文件数。
工作流程:开始工作前先同步,把别人的提交更新到你的本地库;提交前再同步一下,再将别人的提交更新到本地库(这两次同步也可用“拉取”Pull代替,主要保证和别人的commit不冲突,如果是自己的项目就不用这么做了。且一定要commit前做,而不是push前做!否则还是会冲突);之后再提交、推送,更新远程库。

VS Code集成Git工具的使用

同步:先Pull再Push
拉取:fetch
推送:Push
提交:Commit
左上角的小箭头:直接提交所有更改到本地库。

使用Github

watch:可理解为“观察”项目,对于一个项目,默认自己处于Not watching的状态,当你选择Watching,表示你以后会关注这个项目的所有动态,这个项目以后只要发生变动,如被别人提交了pull request、被别人发起了issue等等情况,你都会在自己的个人通知中心,收到一条通知消息,如果你设置了个人邮箱,那么你的邮箱也可能收到相应的邮件。因此watch只用来关注一些你特别在意的项目,若watch得太多通知可能会爆炸…

Star:可理解为“关注”或“点赞”,表示喜欢这个项目。同时github会记录你所有Star的项目,因此Star还可以作为“收藏”功能来用。

fork:可理解为把项目“叉”过来,当选择fork,项目会拷贝到你的repositories中,你自己就有了一份原项目的拷贝,当然这个拷贝只是针对当时的项目文件,如果后续原项目文件发生改变,你必须通过其他的方式去同步。
使用fork的场景:修改开源项目时使用fork,这样你就可以在原项目的基础上,对项目进行修改,并可通过pull request来将修改提交给原作者,如果作者merge了,你就成为这个项目的主人之一了~

团队协作流程:负责人创立一个组织(organization),其他人加入组织,分配权限,之后在这个组织下创建仓库(respository),所有人都向这个仓库提交代码。
关于权限设置:
可以在organization范围内设置权限,即设置成员的write/owner等的权限;
也可以针对respository设置权限,即将成员的ssh key公钥(id_rsa.pub),在res内保存公钥,成员即可对这个仓库提交代码。
关于公钥和私钥:公钥是给外界的,私钥是只自己所有。公钥私钥的主要作用是验证身份,因为只有特定人有权限向仓库提交代码。你在提交时用你的私钥加密,别人用你的公钥就可以验证确实是你(因为私钥只有你自己有)。


Post Date: 2018-09-13

版权声明: 本文为原创文章,转载请注明出处