Git的原理
Git是一种分布式版本控制系统
Git工作区域
如上图所示:Git有四个区域:
区域 | 解释 |
---|---|
本地工作区域(Working Directory) | 写代码的工作目录 |
本地暂缓区(Stage) | 暂缓区仅是一个文件,临时存放代码的改动,保存即将提交到文件列表的信息 |
本地仓库(History) | 安全存放数据的位置,该区域有存放到所有版本的数据,HEAD指向最新放入仓库的版本 |
远端仓库(Remote Directory) | 远程仓库,托管代码的服务器 |
Git文件状态
文件状态 | 解释 |
---|---|
untracked | 未跟踪状态---未将文件加入git库 |
unmodify | 暂缓区中,文件快照内容与文件夹一致---变动1:移除暂缓区到untracked状态 变动2:改动文件到 modified状态 |
modified | 暂缓区中文件被修改---变动1:加入暂缓区到staged状态 变动2:取消修改到 unmodify状态 |
staged | 暂缓区状态---变动1:提交到库中到unmodify状态 变动2:取消修改到modified状态 |
图解文件状态变化
上图所示的文件状态变化:
- 在本地工作目录新创建一个文件 test.txt(untracked状态),通过git add添加到暂缓区(staged状态),最后通过git commit添加到本地仓库。
- 将暂缓区的文件通过 git rm --cached 移除到本地工作目录,文件状态变为(untracked状态)。
上图所示的文件状态变化:
- 通过 git clone 从远程仓库克隆文件到本地工作区,这时所有的文件都是跟踪状态,修改文件hello.java,该文件的状态就会从(unmodify状态)到(modified状态),通过git add添加到暂缓区(staged状态),最后通过git commit添加到本地仓库。
- 如果修改hello.java文件后,想放弃修改的部分,恢复hello.java文件克隆下来的原始状态,可通过*git checkot --*实现,则hello.java文件的状态就从(modified状态)到(unmodify状态)
上图所示的文件状态变化:
- 假设Hi.txt文件是从远程仓库克隆下的文件中的一个文档,修改该文件(modified状态),通过git add添加到暂缓区(staged状态),最后通过git commit添加到本地仓库。
- 提交到本地工作组后再次修改Hi.txt文件,文件的状态就会变为modified状态。
- 修改后的Hi.txt文件通过git add添加到暂缓区(staged状态),可通过 git reset HEAD 将文件的staged状态变为modified状态,即撤销了之前的git add操作。
Git分支介绍
前提与场景设置
- Git有一个默认分支:master分支
- 假设新创建了两个文件hello.java和word.java
操作
- 在hello.java文件和word.java文件添加内容并提交到本地仓库,提交备注为:submit 1
- 修改hello.java文件并提交到本地仓库,提交备注为:submit 2
- 修改word.java文件并提交到本地仓库,提交备注为: submit 3
- 修改hello.java文件并提交到本地仓库,提交备注为:submit 4
- 修改word.java文件并提交到本地仓库,提交备注为: submit 5
- 修改hello.java文件并提交到本地仓库,提交备注为:submit 6
- 修改word.java文件并提交到本地仓库,提交备注为: submit 7
图视化操作
如上图所示:红色代表hello.java的修改记录;蓝色代表word.java的修改
存在问题
若将word.java文件通过Git恢复到submit 3的状态,则hello.java文件的状态也会丢失submit 4和submit 6的修改,因此为了让两个模块的修改与回退不受影响,则需要创建新的分支。
创建test分支
git branch test #创建分支test
git checkout -b test #创建test分支,并切换到test分支
如上图所示:现在存在两个分支master和test(蓝色方块),两个分支是完全一样,都有7次提交,因为test分支是建立在master分支的基础上创建的。
在test分支新提交
修改word.java文件并在test分支上提交,备注为submit 8,产生的效果如下图所示:
如上图所示: test分支有8次提交,master分支有7次提交,如果在test分支上(蓝色方块)仅供word.java文件的相关操作,则不论如何回退都不会影响hello.java文件。 在日常工作中,一个项目是多人合作的,每个人都从主分支拉取一个属于自己的分支开发
HEAD
- Git通过HEAD知道当前用户处于哪个分支,所以当用户切换分支,每次打开Git工作目录都会处于切换的目录
- .git/HEAD文件的内容就是HEAD指针所指向的分支
- HEAD指针 ——–> 分支指针 ——–> 最新提交
HEAD分离头
- 分离头的状态其实就是HEAD指针没有指向分支指针,而是直接指向了某个提交,即HEAD的头指针和分支指针分开了。
- 检出到一个提交就变为分离头状态
- 在分离头状态修改文件,创建提交
- 如果想丢弃上述的提交,则直接检出到一个已经存在的分支上
- 如果想保存上述的提交,使用git checkout -b [分支名称] 创建并检出到一个新的分支,分离头状态的修改就会被保留
Git远程仓库与本地仓库
- 在代码托管平台Bitbucket、GitLab,GitHub、国内比较著名的代码托管平台有码云、coding等的官网上创建一个远程仓库
- 本地仓库与远程仓库连接的两个必要条件是:
- github账号是远程仓库的成员
- github账号中配置了ssh的公钥,ssh的私钥在本地电脑
cd ~/.ssh
ssh-keygen -t rsa -C Git配置的邮箱地址 #生成公钥,遇到提示直接回车,也可设置密码
sudo vi ~/.ssh/id_rsa.pub # 复制ssh的公钥到github账号
Git命令
基本配置
git config --global user.name xxx # 配置全局用户名
git config --global user.email xxx@qq.com # 配置全局邮箱
基本操作
git init # 初始化一个Git仓库
git status # 查看文件状态
git add [files] # 本地工作区的内容提交到本地暂缓区
git commit -m "提交备注" # 本地暂缓区的内容提交到本地仓库
git log # 查看所有分支的提交记录,不包括删除了的commit记录
git reflog # 查看所有分支的提交记录,包括删除了的commit记录
工作区与暂缓区差异比较
git diff # 工作区与暂缓区之间的差异
git diff --cached [file] # 暂缓区与最新提交之间的差异
git diff --staged [file] # 暂缓区与最新提交之间的差异
git diff HEAD # 工作区与最新提交之间的差异
git diff commit-id-1 commit-id-2 # 查看两次提交的差异
git diff commit-id-1..commit-id-2 # 查看两次提交的差异
git diff commit-id-1 commit-id-2 >> diff.txt # 查看两次提交的差异,并输出到文件diff中
回退与撤销
git checkout -- files # 撤销本地工作区的修改
git reset # 重置暂缓区与上一次提交保持一致
git reset HEAD # 重置暂缓区与上一次提交保持一致
git reset –mixed HEAD # 重置暂缓区与上一次提交保持一致
git reset HEAD -- file1 file2 # 针对file1和file2撤销暂缓区的修改
git reset --hard HEAD # 将工作区未提交的与暂缓区修改的都重置到与上一次提交保持一致
git reset --hard commitID # 将工作区和暂缓区回退到指定的提交
远程仓库
git remote -v # 查看远程仓库名称
git remote add [远程仓库名,默认是origin] [远程仓库地址] # 本地仓库关联远程仓库
git push # 如果本地分支和上游的远程分支名字相同,则可使用该命令
git push -u [远程仓库名,默认是origin] [远程仓库分支,默认是master] # 第一次推送本地仓库文件到远程仓库,-u参数会把本地的master分支和远程的master分支关联
git push -u origin test # 推送本地的test分支到远程并关联
git push [远程仓库名] [远程分支] # 本地仓库与远程仓库关联之后的提交命令
git fetch # 将真正的远程分支的更新拉取到本地代表分支,不会更新到本地纯分支
git fetch origin dev # 将远程仓库的dev分支的更新,拉回本地
git pull # git fetch + git merge
分支
git branch [分支名称] # 创建分支
git checkout [分支名称] # 切换到指定的分支
git checkout -b [分支名称] # 创建并切换到指定分支
git branch # 查看当前所在的分支
git merge [分支名称] # 合并指定分支到当前分支
git branch -d [分支名称] # 删除指定分支
git branch -vv # 查看本地仓库与远程仓库的对应关系
git branch -avv # 查看所有的分支
解决冲突
git merge –abort # 遇到冲突后放弃合并
贮藏与更改
git stash # 保存当前分支的更改
git stash pop # 弹出当前的更改
Git实践
Git的安装
Mac上安装Git
- 在终端输入命令:git,查看系统是否安装
- 通过homebrew安装Git: 1.首先安装homebrew:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
2.安装Git
brew install git
Windows上安装Git
- 从官方网站上下载安装包,按照默认配置快速安装(一直下一步)
- git的官方网址:git-scm.com/downloads
- 默认安装完成后,有两种客户端:一种是图形化的客户端,一种是命令行的客户端
- 图形化的客户端被称之为”Git GUI”
- 命令行的客户端被称之为”Git Bash”
- 在系统的”开始”菜单中可以找到”Git GUI”和”Git Bash”,
- 右键菜单中会多出两个选项,”Git GUI Here”和”Git Bash Here”
Git的基本配置
配置用户信息如下:
git config --global user.name "xxx" # 配置用户名
git config --global user.email "xxxxx" # 配置邮箱
git config --list --global # 查看全局配置
config的三个作用域:
git config --local # 缺省是local,使对应配置只针对当前仓库有效
git config --global # 使对应配置针对当前系统用户的所有仓库生效
git config --system # 使对应配置针对系统内所有的用户有效
Git与IDEA相结合
- 在IDEA上导入一个Git项目
点击:File -> New -> Project from Version Control
- IDEA上Git面板介绍
-
拉取远程仓库的代码:
-
提交代码
提交代码分为四个步骤:
- 第1步:点击左下方的"commit"
- 第2步:将本地工作区的改动代码添加到暂缓区(Staged)
- 第3步:在右边填写提交备注
- 第4步:点击右下方的"Commit and Push"
- 查看各个分支的提交记录(具体到文件差异:command + d 查看文章与上一次提交的差异)
4.右键任意一次的提交记录
Copy Revision Number # 复制commit- ID
Create Patch # 创建一个补丁,该提交影响的所有文件的一个列表
Cherry-Pick # 在当前分支把其他分支的代码合并过来
Checkout Revision 'dcfcd731' # 检出到当前的提交
show Respository at Revision # 当前提交下文件目录的一个形态
Compare with Local # 与本地文件的对比
Reset Current Branch to Here # 回退代码到当前提交
Revert Commit # 回退当前的提交
Edit Commit Message # 改写提交信息
Squash Into # 相同信息的提交合并为一个大的提交
Drop Commit # 删除当前的提交
Interactively Rebase from Here # 基于当前的提交域本地库做一个rebase
New Branch... # 基于当前的提交创建一个分支
New Tag... # 创建一个标签
Go to Child Commit # 去子提交
Go to Parent Commit # 去父提交
参考文章
- 《Git学习笔记》juejin.cn/post/688745…
- 《Git》www.zsythink.net/archives/ta…