Git 是目前世界上最先进的分布式版本控制系统。
安装
Windows 下直接官网下,Linux 下可以直接 sudo apt-get install git
。
使用下面的命令来设置本地的账户名字与邮箱地址。
1 | git config --global user.name "Your Name" |
Windows 下出现「Git Credential Manager for Windows」对话框,关闭需要git config --edit --system
,然后删除helper = manager
行。但据说根据环境及安装时行为不同,有不同关闭方案。
每次远程操作都要输密码很烦?某次输入后git config --global credential.helper store
即可。
创建版本库
版本库,就是仓库,英文即为 repository 。
选择一个根目录。
如果你使用 Windows 系统,为了避免遇到各种莫名其妙的问题,请确保目录名(包括父目录)不包含中文。(啊,当然这提醒说不定已经过时了)
第二步,通过git init
命令把这个目录变成 Git 可以管理的仓库。
然后根目录下就会多出一个.git
的隐藏目录,如果你没有看到.git
目录,用ls -ah
命令就可以看见。
把文件添加到版本库
首先这里再明确一下,所有的版本控制系统,其实只能跟踪文本文件的改动,比如 TXT 文件,网页,所有的程序代码等等,Git 也不例外。版本控制系统可以告诉你每次的改动,比如在第 5 行加了一个单词 “Linux” ,在第 8 行删了一个单词 “Windows” 。而图片、视频这些二进制文件,虽然也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制文件每次改动串起来,也就是只知道图片从 100KB 改成了 120KB ,但到底改了啥,版本控制系统不知道,也没法知道。
不幸的是, Microsoft 的 Word 格式是二进制格式,因此,版本控制系统是没法跟踪 Word 文件的改动的,前面我们举的例子只是为了演示,如果要真正使用版本控制系统,就要以纯文本方式编写文件。
因为文本是有编码的,比如中文有常用的 GBK 编码,日文有 Shift_JIS 编码,如果没有历史遗留问题,强烈建议使用标准的 UTF-8 编码,所有语言使用同一种编码,既没有冲突,又被所有平台所支持。使用 Windows 要特别注意:
千万不要使用 Windows 自带的记事本编辑任何文本文件。原因是 Microsoft 开发记事本的团队使用了一个非常弱智的行为来保存 UTF-8 编码的文件,他们自作聪明地在每个文件开头添加了0xefbbbf
(十六进制)的字符,你会遇到很多不可思议的问题,比如,网页第一行可能会显示一个 “?” ,明明正确的程序一编译就报语法错误,等等。这些都是由记事本的弱智行为带来的。
言归正传,把一个文件添加到 Git 仓库需要两步。
- 把文件添加或更新到仓库:
1 | git add <file> |
执行上面的命令,没有任何显示,这就对了,Unix 的哲学是“没有消息就是好消息”,说明添加或修改成功。
- 把文件提交(commit)到仓库:
1 | git commit -m "massage" |
-m
后面输入的字符串是对本次提交的说明,可以输入任意内容,当然最好是有意义的。
掌握工作区状态
git status
命令可以让我们时刻掌握工作区当前的状态。
就比如说原博客给的一个例子:
1 | $ git status |
上面的命令输出告诉我们,readme.txt
被修改过了,但还没有准备提交的修改。
那假如我想要知道readme.txt
哪里被修改了怎么办?这时就需要使用git diff
命令来查看。
例如原博客给的一个例子:
1 | $ git diff readme.txt |
git diff
顾名思义就是查看 difference ,显示的格式正是 Unix 通用的 diff 格式。可以从上面的命令输出看到,我们在第一行添加了一个 distributed 单词。
也可以git diff <file>
来查看单个文件的修改。
查看历史提交记录
git log
指令可以显示从最近到最远的提交日志。
会显示每次提交的 commit id, Author, Date 与我们在提交时写的<message>
。
如果嫌输出信息太多,看得眼花缭乱的,可以使用git log --pretty=oneline
,这样只会显示 commit id 和<message>
。
使用git reflog
可以显示每一次命令,包括提交、回退版本等。
版本回退
首先, Git 必须知道当前版本是哪个版本,在 Git 中,用 HEAD
表示当前版本,也就是最新的提交,上一个版本就是 HEAD^
,上上一个版本就是 HEAD^^
,当然往上 100 个版本写 100 个 ^
比较容易数不过来,所以写成 HEAD~100
。
就比如说git reset --hard "HEAD^"
就回退到上一个版本。
所以说回退版本的命令就是:
1 | git reset --hard <commit_id> |
这样就回退到你需要的版本了。
但是如果要恢复新版本怎么办?
通过git reflog
查看新版本对应的 commit id ,也使用上述指令即可。
Git 的版本回退速度非常快,因为 Git 在内部有个指向当前版本的HEAD
指针,当你回退版本的时候, Git 仅仅是把HEAD
修改,然后顺便把工作区的文件更新。所以不仅可以回到历史版本也可以返回新版本。
工作区与暂存区的概念
工作区
即直接能看到的目录。
版本库
打开显示隐藏目录,会发现.git
目录。这个不算工作区,而是 Git 的版本库。
Git 的版本库中存了很多东西,比如称为 stage 或 index 的暂存区,及每个分支,指针HEAD
。
回忆我们怎么把文件往 Git 版本库里添加:
git add
,把文件加入暂存区。git commit
,提交更改,即把把暂存区的所有内容提交到当前分支。
所以你在git status
后看到的三类文件大概就是:
Untracked files
,从来未被添加过的文件。Changes not staged for commit
,在工作区修改了但没有将修改加入暂存区的文件。Changes to be commited
,加入了暂存区,还没有提交到分支的文件。
当我们加入某个文件到暂存区,之后再将其修改,未重新加入缓存区后提交到分支,则分支中的版本为先前暂存区中的版本。
可以使用git diff HEAD -- <file>
验证。