理解
快照而非增量更新
增量更新其它版本系统把版本看成一组基础文件以及在上面进行的增量操作。
快照
Git把版本看成一组文件的快照,每一次提交保存的都是文件在提交时刻的状态。
操作本地化
由于Git在本地保存了完整的仓库,因此除非你需要与远程同步代码,或者推送代码到远程仓库,几乎所有操作都可以在本地进行。在没有网络或者VPN的时候,你依然可以修改提交代码,查看文件历史版本,创建新分支或者合并分支。
完整性保障
Git内部使用SHA-1
哈希算法来计算文件、目录结构或提交信息的校验值。使用Git时你会看到大量类似这样的24b9da6552252987aa493b52f8696cd6d3b00373
校验值。Git内部数据库使用文件内容的校验值而非文件名来保存文件。因此你不可能避开Git而随意修改文件内容、目录结构或者提交信息。举个简单的例子,提交信息中包含目录结构校验值,目录结构中包含文件的校验值;如果修改了文件内容,那么文件校验值会随之改变,进而会导致目录结构校验值改变,最终会导致提交校验值改变。(有点像区块链)
只增加数据
Git通常指往仓库增加数据,你很难主动删除已经保存在仓库的内容。在未提交的时候,你可能丢失数据或者弄乱文件,但是一旦你提交到仓库中,你就很难把数据删除了。所以在使用git时你可以做各种各样的实验,而不用担心把已提交数据弄乱。
工作区域与文件状态
工作区、暂存区和Git仓库三个工作区域 - 工作区、暂存区和Git仓库
- 工作区 - 从仓库中检出(
checkout
)的特定版本文件,供你使用和修改 - 暂存区 - 暂存区域是一个文件,用于保存下次提交的文件列表信息
- Git仓库 - Git用来保存项目元数据和对象数据库的地方(
.git/
)
四种文件状态 - 未跟踪、已修改、已暂存和已提交
- 未跟踪 - 所有未纳入Git管理的文件都处于未跟踪(
untracked
)状态 - 已跟踪 - 所有已纳入Git管理的文件都处于已跟踪(
tracked
)状态- 未修改 | 已提交 - 当你将已暂存文件提交到本地仓库中时,文件处于未修改(
unmodified
)或者叫已提交(committed
)状态 - 已修改 - 当文件在工作区中被修改时,文件处于已修改(
modified
)状态 - 已暂存 - 当一个已修改文件被标记用于下次提交时,文件处于已暂存(
staged
)状态
- 未修改 | 已提交 - 当你将已暂存文件提交到本地仓库中时,文件处于未修改(
文件状态生命周期
文件状态生命周期- 未跟踪 → 已暂存:将新文件纳入Git管理
- 未修改 → 已修改:修改工作区文件
- 已修改 → 已暂存:将工作区修改好的文件添加到暂存区
- 未修改 → 未跟踪:将原先由Git管理的文件移除管理
- 已暂存 → 未修改:将暂存区的文件提交
基本工作流
- 在工作目录中修改文件
- 暂存已修改文件,这会将文件快照放入暂存区域
- 提交更新,生成一次新的提交,该提交会保存暂存区域所有文件的快照并将其永久存储到Git仓库
配置
配置文件路径
-
/etc/gitconfig
- 全局配置文件,使用git config --system option value
来进行配置 -
~/.gitconfig
- 单用户配置文件,使用git config --global option value
来进行配置 -
.git/config
- 单仓库配置文件,仓库根目录使用git config option value
来进行配置
备注1:配置优先级 - 单仓库配置文件 >
单用户配置文件 >
全局配置文件
备注2:可以使用git config --system --edit
| git config --global --edit
| git config --edit
来直接编辑配置文件
必要配置
- 配置用户名 -
git config --global user.name "Jian Zhang"
- 配置邮箱 -
git config --global user.email zhangjian@example.com
SSH公钥配置
目的:允许使用SSH协议克隆仓库、拉取以及推送代码
优点:一次配置,永久生效,无需每次输入用户名和密码
示例:git clone git@github.com:google/guava.git
生成SSH公钥和私钥
$ ssh-keygen -t rsa -b 4096 -C "zhangjian@example.com" # 之后一直回车即可
将SSH公钥内容复制粘贴到GitHub账号设置
$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCu5ncRBtZCASrIAcHob+ZUQcHj+rQPEQJwGQbSYsGfLW8vpwVVC+8kMofXtkda2MBuZVApFfYg3UPojFz/m1XkqhKFyYIa/xqeqWiVDuMXznhf++/t1jYu8kUXTWqqYcQXMse4LIuNVXvfbQ4Jy+ZIg8Iw0XSXHpy4UevXpUdkzEExkT4ar0asdfa2b5Z/3kjbWRlHaJms9K13FH4G4glNY5oFC0kuvYJDxxxG4EscFHbkE58kEMk3e/CtYVcdSV5fMYXP2y60bLT+L5Ac2y+qDjuLcNX1BAF7/S9/eNXySe98CBbejDJTO2bzDQmixZwrq0LqNLxXMHOAl/Is5 zhangjian@example.com
GitHub SSH公钥配置
可选配置
配置别名
- git co -
git config --global alias.co checkout
- git br -
git config --global alias.br branch
- git ci -
git config --global alias.ci commit
- git st -
git config --global alias.st status
配置编辑器
-
git config --global core.editor vim
|git config --global core.editor emacs
配置命令
-
git config option
- 查询单个配置信息
$ git config user.name
Jian Zhang
-
git config -l
|git config --list
- 查询所有配置信息
$ git config -l
user.name=Jian Zhang
user.email=zhangjian@example.com
alias.co=checkout
alias.br=branch
alias.ci=commit
alias.st=status
core.editor=vim
帮助
-
git --help
- 获取帮助 -
git help command
|git command --help
|man git-command
- 获取单个命令帮助
资源
初始化仓库
-
git init
- 在已有目录中初始化仓库
$ mkdir project && cd project && git init
Initialized empty Git repository in /Users/zhangjian/workspace/project/.git/
$ tree -a
.
└── .git
├── HEAD
├── config
├── description
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ ├── pre-receive.sample
│ ├── prepare-commit-msg.sample
│ └── update.sample
├── info
│ └── exclude
├── objects
│ ├── info
│ └── pack
└── refs
├── heads
└── tags
9 directories, 14 files
-
git clone URL
- 从远程仓库克隆已有项目
$ git clone git@github.com:google/guava.git # 使用SSH协议
$ git clone https://github.com/google/guava.git # 使用HTTPS协议
基础操作
-
git add file
|git add directory
- 跟踪新文件
$ touch README; git status
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
README
nothing added to commit but untracked files present (use "git add" to track)
---------------------------------------------------------------------------------------------------
$ git status -s
?? README # 此处??为红色,代表文件未被跟踪
---------------------------------------------------------------------------------------------------
$ git add README; git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: README
---------------------------------------------------------------------------------------------------
$ git status -s
A README # 此处A为绿色,代表文件为新添加文件,并且已经暂存
-
git add file
- 暂存已修改文件
$ echo "abc" > README; git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: README
no changes added to commit (use "git add" and/or "git commit -a")
---------------------------------------------------------------------------------------------------
$ git status -s
M README # 此处M为红色,在右边,代表文件已修改但是未暂存
---------------------------------------------------------------------------------------------------
$ git add README; git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README
---------------------------------------------------------------------------------------------------
$ git status -s
M README # 此处M为绿色,在左边,代表文件已修改并且已暂存
-
git status
|git status -s
- 查看文件状态-
??
- 该文件未被跟踪,未纳入Git管理 -
_M
- 该文件已修改,但是尚未暂存 -
M_
- 该文件已修改,并且已经暂存 -
MM
- 该文件已修改,并且已暂存,但是暂存之后再次被修改,再次修改的内容尚未暂存 - 待补充
-
$ touch README; git status
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
README
nothing added to commit but untracked files present (use "git add" to track)
---------------------------------------------------------------------------------------------------
$ git status -s
?? README
网友评论