特点-分布式版本控制系统
集中式版本控制系统(CVCS)
这类系统,诸如 CVS,Subversion 以及 Perforce 等,都有一个单一的集中管理的服务器,保存所有文件的修订版本。协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。
分布式版本控制系统(DVCS)
每个人的电脑上都有一份完成的服务器代码仓库的镜像。每一次的提取操作,实际上都是一次对代码仓库的完整备份。
Git和其他版本控制系统的差别
Git 只关心文件数据的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异。Git 并不保存这些前后变化的差异数据, 更像是把变化的文件作快照后,记录在一个微型的文件系统中。
其他系统:

Git:

几乎所有操作都是本地执行
仓库的基本概念
远程仓库(Remote)
资源库,是远程机器上的代码库,用于做不同版本库文件交换更新。如Gitlab,GitHub,gitee。【基于Git的Web协作平台。它们提供了一个中心化的服务器来托管你的Git仓库,并在此基础上添加了大量用于团队协作和项目管理的Web功能。】
本地库(Repository)
用户在本地创建的目录,拥有远程库的一个快照,由工作区和版本库(就是仓库)构成。
工作区(Workspace)
本地库的根目录中除.git目录以外的内容,存储内容的实际文件。
暂存区( stage /Index)
缓存区,暂存信息存放在.git目录"下的index文件(.git/index)中,用于临时保存内容的修改。
版本库(.git目录)
本地库的根目录中的一个隐藏目录.git,用于记录版本信息,Git进行版本控制所需要的文件,则都放在.git文件夹中;
分支(Branch)
本地库中默认创建一个主(master)分支,分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作。
Git仓库工作流程
- 克隆远程库:从远程库上克隆完整的Git仓库(包括代码和版本信息)到本地;
- 在本地库上修改代码:在本地库上根据不同的开发目的,创建分支,修改代码;
- 提交到分支:在本地分支上提交代码;
- 把修改合并到本地主分支:在本地库上提交更新,也就是说,把修改合并到本地主分支;
- 把远程库合并到本地主分支:把远程库上的最新代码fetch下来,跟本地主分支合并,如果存在冲突,那么解决冲突。
- 把本地主分支提交到远程库:生成补丁(patch),把补丁发送给远程库。
Git命令

初始化和配置
bash
git config --global user.name "你的名字" 设置全局用户名
git config --global user.email "你的邮箱" 设置全局邮箱
git init 将当前目录初始化为一个新的Git仓库
git clone <仓库URL> 克隆一个远程仓库到本地
日常基本操作
bash
git status 查看工作区和暂存区的状态(哪些文件被修改、哪些已暂存)
git add <文件名> 将指定文件的修改添加到暂存区
git add . 或 git add -A 将所有修改(新文件、修改、删除)添加到暂存区
git commit -m "提交信息" 将暂存区的内容提交到本地仓库,并附上提交说明
git commit -am "提交信息" 一次性add已跟踪文件的修改并commit(对新文件无效)
git restore <文件名> 丢弃工作区中指定文件的修改(Git 2.23+)
git restore --staged <文件名> 将文件从暂存区撤出,但保留工作区的修改(Git 2.23+)
git rm <文件名> 删除工作区文件,并将这次删除放入暂存区
查看提交历史
bash
git log 查看提交历史
git log --oneline 以简洁的单行模式查看历史
git log --graph 以图形化方式查看分支合并历史
git show <commit_id> 查看某一次提交的详细内容变更
分支管理
bash
git branch 列出所有本地分支(当前分支前有*号)
git branch <分支名> 创建一个新分支
git checkout <分支名> 切换到指定分支
git switch <分支名> 切换到指定分支(更语义化的新命令,Git 2.23+)
git checkout -b <分支名> 创建并切换到新分支
git switch -c <分支名> 创建并切换到新分支(Git 2.23+)
git merge <分支名> 将指定分支合并到当前分支
git branch -d <分支名> 删除指定分支(如果该分支已被合并)
git branch -D <分支名> 强制删除指定分支(即使未被合并)
远程仓库协作
bash
git remote -v 查看远程仓库地址(verbose详情)
git push origin <分支名> 将本地分支推送到远程仓库
git push -u origin <分支名> 推送并设置上游分支,以后可以直接git push
git pull origin <分支名> 拉取远程分支的最新更改并合并到当前分支
git fetch origin 仅从远程仓库获取最新信息,但不自动合并
git remote add origin <仓库URL> 添加一个远程仓库地址,并命名为origin
撤销与回退
bash
git restore <文件名> 撤销工作区的修改,恢复到最近一次git commit或git add的状态
git restore --staged <文件名> 将文件从暂存区(Staging Area)移回工作区,取消git add操作
git reset --soft <commit_id> 回退到某个提交,保留工作区和暂存区的内容
git reset --mixed <commit_id> 默认选项。回退到某个提交,保留工作区,但重置暂存区
git reset --hard <commit_id> 彻底回退,工作区、暂存区都重置到指定提交的状态(谨慎使用!)
git revert <commit_id> 创建一个新的提交来"撤销"某次提交的更改,更安全,适用于公共分支
储藏临时工作
bash
git stash 将当前工作区和暂存区的修改临时储藏起来
git stash list 查看所有的储藏列表
git stash pop 恢复最近一次储藏的工作内容,并删除该储藏
git stash apply 恢复储藏的工作内容,但不删除储藏
.gitignore文件
在项目中,我们可能一起提交多个文件
· git add -A 提交所有变化
· git add -u 提交被修改(modified)和被删除(deleted)文件,不包括新文件(new)
· git add . 提交新文件(new)和被修改(modified)文件,不包括被删除(deleted)文件
可以创建一个名为 .gitignore 的文件,列出要忽略的文件模式,Git会根据这些模式规则来判断是否将文件添加到版本控制中。
格式规范
· 所有空行或者以注释符号 # 开头的行都会被 Git 忽略
· 可以使用标准的 glob 模式匹配
· 匹配模式最后跟斜杠(/)说明要忽略的是目录
· 要忽略指定模式以外的文件或目录,可以在模式前加上感叹号(!)进行取反
glob模式
指 shell 所使用的简化了的正则表达式,匹配规则如下:
"*":星号匹配零个或多个任意字符
\]:匹配任何一个列在方括号中的字符,如\[ab\]匹配a或者匹配b
"?":问号匹配一个任意字符
\[n-m\]:匹配所有在这两个字符范围内的字符,如\[0-9\]表示匹配所有0到9的数字
### 全局.gitignore文件
这种方式在不同的项目开发者之间是不共享的,是属于项目之上Git应用级别的行为。
可以在任意目录下创建相应的.gitignore文件,然后再使用以下命令配置Git
```bash
git config --global core.excludesfile ~/.gitignore
```
> .gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。所以一定要养成在项目开始就创建.gitignore文件的习惯。
### java开发通用模板
```java
#java
*.class
#package file
*.war
*.ear
*.zip
*.tar.gz
*.rar
#maven ignore
target/
build/
#eclipse ignore
.settings/
.project
.classpatch
#Intellij idea
.idea/
/idea/
*.ipr
*.iml
*.iws
# temp file
*.log
*.cache
*.diff
*.patch
*.tmp
# system ignore
.DS_Store
Thumbs.db
```
## diff命令
显示不同版本、不同区域之间的差异
| 命令 | 比较对象 | 使用场景与说明 |
| **`git diff`** | **工作目录 vs 暂存区** | **最常用** 。查看你自从上次`git add`之后,**在工作区做了哪些修改**(尚未暂存的)。如果没有任何未暂存的修改,这个命令没有输出。 |
| **`git diff --staged`** 或 **`git diff --cached`** | **暂存区 vs 最后一次提交** | 查看所有已经通过 `git add` 暂存起来的文件,与最后一次提交之间的差异。这些差异将会被下一次 `git commit` 提交。 |
| **`git diff HEAD`** | **工作目录 vs 最后一次提交** | 查看**工作目录**与最后一次提交之间的所有差异(包括已暂存和未暂存的)。这是最全面的本地更改视图。 |
| **`git diff