名词解释:
- working directory:工作区,本地电脑上的工作目录文件夹;
- Staging area:暂存区,暂存工作区的文件变化,或者叫索引( index or staging area ),这里面的代码会在下一次commit被提交到Git仓库;
- repository:版本库,由Git object记录着每一次提交的快照,以及链式结构的提交变更历史。;
- 远程仓库:即Github或Gitee;
- Index:索引,是暂存区的另一种术语,即暂存区的别名;
- Checkin:签入,将新版本复制回仓库;
- Checkout:签出,从仓库中将文件的最新修订版本复制到工作区;
- Commit:提交,将暂存区的文件提交到仓库;
- Conflict:冲突,多人对同一文件的同一部分进行了修改,导致了冲突的发生;
- Merge:合并,将指定分支合并到当前分支,git merge dev是将dev分支合并到当前分支中;
- Branch:分支,从当前分支上分离开的副本,分支是用来标记特定代码的提交,每一个分支通过SHA1sum值来标识,所以对分支的操作是轻量级的,你改变的仅仅是SHA1sum值
- HEAD:头,指向当前选择的分支,在.git目录里,就是一个文件,其内容指向refs目录下的文件:ref: refs/heads/master或者ref: refs/heads/dev,而这个目录下的master或dev文件,则是一个commit的SHA1;
- Revision:修订,表示代码的一个版本状态。Git通过用SHA1 hash算法表示的ID来标识不同的版本。
- Tags:标记,标记某个分支的某一个版本,方便检索和查看。
- Push,推送,向远程仓库推送当前分支;
- Pull:拉取,从远程仓库拉取文件,并合并入当前分支,git pull 是将远程主机的最新内容拉下来后直接合并,即:git pull = git fetch + git merge,这样可能会产生冲突,需要手动解决。
- fetch:提取,git fetch是将远程主机的最新内容拉到本地,用户在检查了以后决定是否合并到工作本机分支中,git fetch origin dev取回origin 主机的dev分支(不会merge);
- Untracked: 未跟踪文件。此文件仅在工作区中,暂存区和版本库没有它,未进行版本控制。 新建或新增一个文件即产生一个未追踪文件。通过git add 将其加入暂存区,即成为已追踪文件;
- Unmodified: 未修改文件。文件已经入库,未修改,即版本库中的文件快照内容与工作区中完全一致。 这种类型的文件有两种去处, 如果它被修改, 而变为Modified. 如果移出版本库, 则成为Untracked文件;
- Modified: 已修改文件,已版本控制的文件在工作区中被修改了,还未加入暂存区。 这个文件也有两个去处, 通过git add可进入暂存staged状态。使用git restore – 命令丢弃修改, 返回到unmodify状态;
- Staged: 已暂存,文件已经进入暂存区。
- Git object文件类型(./git/objects目录里)有:blob、tag、tree、commit,用git cat-file -t objects文件下的文件查看类型值(目录名+文件名)下面有图;
- blob类型:存储内容,比如代码、配置文件内容等;
- tag类型:
- tree类型:存储代码的目录结构,每一个文件(或者子文件夹)的权限、类型、对应的身份证(SHA1值)、以及文件名,执行commit命令时会自动生成;
- commit类型:存储提交的信息,包括tree的哈希值,上一个提交的哈希值,提交的作者以及提交的具体时间,最后是该提交的信息。
文件状态流转如下:
举例说明:
- 在工作区新建一个文件 a.txt 。 此时文件状态为 Untracked
- 执行 git add a.txt 。 此时文件状态为 Staged。
- 修改 a.txt 文件并保存,此时文件状态为 Modified。
- 执行 git add a.txt 。 此时文件状态又为 Staged。
- 执行 git commit -m ‘提交a文件‘ ,此时文件状态变为 Unmodified。
- 执行 git rm --cached a.txt 。此时工作区的a.txt变为Untracked状态。
暂存、提交命令执行时,.git目录的文件变化
7. 每次git add .暂存所有修改,都会在objects目录里生成新的目录及blob类型文件(新增数量是修改文件数+新增文件数,一个修改/新增的文件对应一个单独的目录),用于保存全新的内容(是完全备份,不是增量备份);
8. 每次git commit,也会重新在objects目录里再生成2组目录及文件,分别:生成新的commit类型文件及其目录,用于保存提交信息等;同时生成新的tree类型文件及其目录,用于保存最新的文件结构,指向最新的文件和未修改文件;
9. 一个commit文件下就指向一个tree文件,一个tree文件指向所有受控文件(也含没修改的文件),多个commit就对应多个下面的树形结构
10.head文件内容(sha1值)指向master文件,master文件内容(sha1值)指向最新的commit文件,所以可以从.git/head文件开始找结构;
操作命令图解
Git 全局配置查看修改
- git config:config 配置有system级别 global(用户级别) 和local(当前仓库)三个 设置先从system-》global-》local 底层配置会覆盖顶层配置 分别使用–system/global/local 可以定位到配置文件
- 查看当前用户配置:git config --global --list
- 查看当前仓库配置信息:git config – local --list
- 新增当前用户配置:git config --global user.emal=abc@163.com
- 删除当前用户配置:git config --global --unset user.emal
操作命令解释
- 创建版本库
v- git init: - 把文件添加到版本库
- git add .:把文件添加到暂存区中
- git commit -m “”:把文件添加到版本库中
- 查看仓库状态
- git status:
- 要么有新文件,还没添加到暂存区,Untracked files
- 要么有文件修改(modified),还没添加到暂存区,Changes not staged for commit
- 要么是添加到暂存去了(new file或者modified),但还没提交(commit),Changes to be committed:
- 要么是没新增修改任何文件,nothing to commit, working tree clean
- git status:
- 查询/对比修改内容
- git diff readme.txt
- 版本回退
- git reset --hard HEAD^:把当前的版本回退到上一个版本
- git reset --hard HEAD^^:回退到上上个版本:
- git reset --hard HEAD~100:把当前的版本回退到前第100个版本
- git reset --hard 版本号:往前或往后,回退到指定版本
- 查看版本历史记录
- git log:查看历史记录,注释里的中文乱码解决
git config --global core.quotepath false
git config --global gui.encoding utf-8
git config --global i18n.commit.encoding utf-8
git config --global i18n.logoutputencoding utf-8
# bash 环境下
export LESSCHARSET=utf-8
# cmd环境下:
set LESSCHARSET=utf-8
- git log --pretty=oneline
- git reflog:查看历史记录的版本号id
-
撤销修改
- 添加到暂存区操作前,丢弃工作区的修改:git reset readme.txt;
- 已提交到暂存区的,先撤销暂存区文件,再撤销文件的修改
- git restore --staged readme.txt
- git restore readme.txt
-
删除/恢复文件
- 删除:直接在文件目录下删除文件,再commit提交;
- 恢复:git restore readme.txt,从版本库恢复readme.txt;
-
添加远程仓库
- git remote add origin https://github.com/xxx/xxx.git
- git push -u origin master,将本地库的内容推送到远程,第一次推送master分支时,加上了 –u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,同理在home分支上执行:git push -u origin home,就是把本地的home分支推送到远程仓库,并创建分支home且关联了,在以后的推送或者拉取时就可以简化命令;
-
后续把本地master分支的最新修改推送到
- git push origin master
-
从远程仓库克隆版本库到本地
- git clone https://github.com/xxx/xxx.git
-
创建+切换分支
- git checkout -b dev, –b参数表示创建dev并切换到dev分支,相当于如下2条命令
- git branch dev,创建分支
- git checkout dev,切换分支
- git checkout -b dev, –b参数表示创建dev并切换到dev分支,相当于如下2条命令
-
说明:HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是当前分支。
-
查看所有分支
- git branch,查看本地所有分支,当前分支前面会添加一个星号
- git branch -a,查看本地和远程的所有分支
- git branch -r,查看远程所有分支
-
切换分支
- git checkout 分支名称
-
合并分支
- 在master分支上,使用命令 git merge dev(合并指定分支dev到当前分支上)
- Fast-forward,快进模式的合并,也就是直接把master指向dev的当前提交,所以合并速度非常快。
-
删除分支
- git branch –d name
-
git cat-file -t:因为Git将信息压缩成二进制,要查看objects目录下文件的类型(有4种类型)用此命令,比如:git cat-file -t f67f,其中f6是目录名;
-
git cat-file -p:查看objects目录下文件的内容,比如git cat-file -p bc36ba;
-
分支管理策略
- 首先master主分支应该是非常稳定的,也就是用来发布新版本,一般情况下不允许在上面干活,干活一般情况下在新建的dev分支上干活,干完后,比如上要发布,或者说dev分支代码稳定后可以合并到主分支master上来。
- 在开发中,会经常碰到bug问题,那么有了bug就需要修复,在Git中,分支是很强大的,每个bug都可以通过一个临时分支来修复,修复完成后,合并分支,然后将临时的分支删除掉。
-
多人协作开发
- 基于dev分支开发,经理需先把dev分支推送到服务端,即服务端要先存在dev分支以供小组成员下载,经理用命令git push origin dev把本地的dev分支推送到服务端;
- 小组成员用命令创建并下载dev分支:git checkout –b dev origin/dev,开始基于dev分支开发;
- 小组成员开发完成后本地先提交(git add .和git commit),再把dev分支推送到远程库,用命令:git push origin dev,把dev推送到服务端;
- 经理或其他成员就可以用git pull origin dev下载最新的dev分支代码;
- 关联本地dev分支与远程origin/dev分支的链接命令:git branch --set-upstream-to=origin/dev dev,关联目的是在执行git pull, git push操作时就不需要指定对应的远程分支,直接操作当前所在分支;
- git push -u和git branch --set-upstream-to:git push -u origin mybranch1 相当于 git push origin mybranch1 + git branch --set-upstream-to=origin/mybranch1 mybranch1,前者-u时创建远程分支并关联分支,后者仅是关联分支;
-
objects目录里的文件类型、文件内容截图