很多人都知道,林纳斯·托瓦兹在1991年创建了开源的Linux,从此,Linux系统不断发展,已经成为最大的服务器系统软件了。
Git是一种代码托管技术。在开发中,Git是一种代码托管技术,很多代码托管平台也是基于Git来实现的。Git可以帮我们做到很多的事情,比如代码的版本控制,分支管理等。
注意:
我们可以把Git理解成是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。正是因为有了Git的存在,现在很多工作才可以变得相对轻松。
你可以把一个版本控制系统(缩写VCS)理解为一个“数据库”,在需要的时候,它可以帮你完整地保存一个项目的快照。当你需要查看一个之前的快照(称之为“版本” )时,版本控制系统可以显示出当前版本与上一个版本之间的所有改动的细节。
想法:
因为我们怕在原来的基础改错了东西,没法恢复,所以,我们可能会有多个毕业论文的文件。而我们写代码的时候本身就是「多人协作」的,修改是无法避免的,我们不希望有多个文件的产生,又希望能够记录每次更改的内容。“
这个软件用起来就应该像这个样子,能记录每次文件的改动:
版本 | 文件名 | 用户 | 说明 | 日期 |
---|---|---|---|---|
1 | service.doc | 张三 | 删除了软件服务条款5 | 7/12 10:38 |
2 | service.doc | 张三 | 增加了License人数限制 | 7/12 18:09 |
3 | service.doc | 李四 | 财务部门调整了合同金额 | 7/13 9:51 |
4 | service.doc | 张三 | 延长了免费升级周期 | 7/14 15:17 |
注意:
结束了手动管理多个“版本”的史前时代,进入到版本控制的20世纪。
集中式版本控制系统需要找一个服务器作为大本营,所有的代码都需要提交到服务器上进行统一的管理。当你需要对代码进行改动时,需要先从服务器上下载一份拷贝,修改完成之后,还需要上传回服务器。
优点:
缺点:
在分布式版本控制系统中,大家都拥有一个完整的版本库,不需要联网也可以提交修改,所以中心服务器就显得不那么重要了。
注意:
Git记录版本历史==只关心文件数据的整体是否发生变化。==Git 不保存文件内容前后变化的差异数据。
优点:
缺点:
Workspace: 工作区,就是你平时存放项目代码的地方
Index / Stage: 暂存区,用于临时存放你的改动,事实上它只是一个文件,保存即将提交到文件列表信息
Repository: 仓库区(或版本库),就是安全存放数据的位置,这里面有你提交到所有版本的数据。其中HEAD指向最新放入仓库的版本
Remote: 远程仓库,托管代码的服务器,可以简单的认为是你项目组中的一台电脑用于远程数据交换
Git的工作流程一般是这样的:
注意:
在Windows操作系统中安装 Git之前,先从官方网站(https://git-scm.com/)下载合适的Git版本。
当安装Git后首先要做的事情是设置用户名称和email地址。这是非常重要的,因为每次Git提交都会使用该用户信息。
git config --global user.name "oldGj_"
git config --global user.email "[email protected]"
检查当前的设置
git config --list
git config user.name
注意:
通过上面的命令设置的信息会保存在~/.gitconfig文件中。
版本控制就是对文件的版本控制,要对文件进行修改、提交等操作,首先要知道文件当前在什么状态,不然可能会提交了现在还不想提交的文件,或者要提交的文件没提交上。
注意:
Git不关心文件两个版本之间的具体差别,而是关心文件的整体是否有改变,若文件被改变,在添加提交时就生成文件新版本的快照,而判断文件整体是否改变的方法就是用SHA-1算法计算文件的校验和。
未跟踪, 此文件在文件夹中, 但并没有加入到git库, 不参与版本控制. 通过git add 状态变为Staged.
被纳入版本控制
Unmodified
文件已经入库, 未修改, 即版本库中的文件快照内容与文件夹中完全一致. 这种类型的文件有两种去处, 如果它被修改, 而变为Modified,如果使用git rm移出版本库, 则成为Untracked文件。
Modified
文件已修改, 仅仅是修改, 并没有进行其他的操作. 这个文件也有两个去处, 通过git add可进入暂存staged状态, 使用git checkout 则丢弃修改过,返回unmodify状态, 这个git checkout即从库中取出文件, 覆盖当前修改。
Staged
暂存状态. 执行git commit则将修改同步到库中, 这时库中的文件和本地文件又变为一致, 文件为Unmodify状态. 执行git reset HEAD filename取消暂存,文件状态为Modified。
注意:
这些文件的状态会随着我们执行Git的命令发生变化
注意:
- 新建文件—>Untracked
- 使用add命令将新建的文件加入到暂存区—>Staged
- 使用commit命令将暂存区的文件提交到本地仓库—>Unmodified
- 如果对Unmodified状态的文件进行修改—> modified
- 如果对Unmodified状态的文件进行remove操作—>Untracked
查看文件状态命令
语法结构:
git status
参数:
- -s: 简洁输出
例子
$ git status
On branch master
No commits yet
Untracked files:
(use "git add ..." to include in what will be committed)
a.txt
语法结构
git add 文件名
语法结构
git reset 文件名
如果仅是通过git add命令把移动加到暂存区,还不算是完成整个流程。如果想让暂存区的内容永久保存下来,就要使用git commit命令。
语法结构:
git commit -m "提交信息"
参数:
- -m : 本次提交做了什么事,只要简单、清楚的文本说明即可,中英文都可以重点是说清楚,能让自己和别人很快明白就行。
如果不加m参数,会进入类似vim编辑。
身为程序员,难免会遇到一些不太顺心的客户或项目。心情不好的时候,在代码或Commit信息中“发泄”一下情绪也是很常见的,只是这要是让客户看见了总是不好解释。
要改动Commit记录有几种方式。
git log --oneline
只需要在Commit命令后面加上–amend即可
git commit --amend -m "welcome to facebook"
语法结构:
git rm 文件名
注意:
删除的文件只是删除工作目录的文件,我们的版本库里面还是存在的。 删除文件会把这个文件直接放入暂存区。
“人有失手,马有失蹄”,人总会有不小心或状态不好的时候。不管是有意还是无心 在Git中如果不小心把文件或目录删除了,是可以挽救回来的,这也是使用版本控制系统最主要的原因之一。
这里先使用rm命令,故意把项目中所有的HTML文档删除:
rm *.html
ls -al
可以看出当前1个文件都处于被删除(deleted)状态。
可以使用git checkout命令:
git checkout index.html
注意:
当使用git checkout命令时,Git 会切换到指定的分支,但如果后面接的是文件名或路径,Git则不会切换分支,而是把文件从.git目录中复制一份到当前的工作目录。更精准地说,这个命令会把暂存区中的内容或文件拿来覆盖工作目录中。
如果想把所有删除文件都挽救回来,可以使用以下命令:
git checkout .
小技巧:
这个技巧不仅可以将删除的文件挽救回来,当改动某个文件后反悔了,也可以用它把文件恢复到上一次Commit的状态。不是所有情况下都能恢复被删除的文件的。因为整个Git的记录都是放在根目录下的 .git目录中,如果这个目录被删除了,也就意味着历史记录也被删除了,那么删除的文件也就不能恢复了。
一般我们总会有些文件无需纳入Git的管理,也不希望它们总出现在未跟踪文件列表。通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。在这种情况下,我们可以在工作目录中创建一个名为 .gitignore的文件(文件名称固定),列出要忽略的文件模式。
# / 表示 当前文件所在的目录
# 忽略public下的所有目录及文件
/public/*
#不忽略/public/assets,就是特例的意思,assets文件不忽略
!/public/assets
# 忽略具体的文件
index.class
# 忽略所有的class
*.class
# 忽略 a.class b.class
[ab].class
注意:
- #匹配规则和linux文件匹配一样
- #以斜杠“/”开头表示目录
- #以星号“*”通配多个字符
- #以问号“?”通配单个字符
- #以方括号“[]”包含单个字符的匹配列表
- #以叹号“!”表示不忽略(跟踪)匹配到的文件或目录
例子
手动创建一个user.class文件
touch user.class
touch userDao.class
创建.gitignore文件
touch .gitignore
编写规则
*.class
语法结构:
git log
参数:
- –graph : 查看分支合并图
- –oneline : 标记把每一个提交压缩到了一行中
语法结构:
git reflog
diff是指的是两个事物的不同。例如在Linux系统中,diff命令会逐行比较两个文本的差异然后显示出来。
语法结构:
git diff [--cached]
注意:
---
:标记原始文件+++
:标记新文件@@
:两个不同文件版本的上下文行号。-
: 原始文件删除改行+
:原始文件增加一行
工作文件夹比较
git diff
把修改文件追加到索引区
git add .
无法比较工作文件夹的修改文件
git diff
索引区比较
git diff --cached
对于恢复修改的文件,就是将文件从仓库中拉到本地工作区,即 仓库区 ----> 暂存区 ----> 工作区。
对于修改的文件有三种情况:
只是修改了文件,没有任何 git 操作,直接一个命令就可回退
$ git checkout -- aaa.txt # aaa.txt为文件名
修改了文件,并提交到暂存区(即编辑之后,git add但没有gitadd但没有 git commit )
$ git log --oneline # 可以省略
$ git reset HEAD # 回退到当前版本
$ git checkout -- aaa.txt # aaa.txt为文件名
注意:
情况II 和 情况III 只有回退的版本不一样,对于 情况II,并没有 $ git commit,仓库版本也就不会更新和记录,所以回退的是当前版本
修改了文件,并提交到*仓库区*(即编辑之后git add和gitadd和 git commit -m )
$ git log --oneline # 可以省略
$ git reset HEAD^ # 回退到上一个版本
$ git checkout -- aaa.txt # aaa.txt为文件名
注意:
git reset 版本号 ---- 将暂缓区回退到指定版本,根据 $ git log --oneline 显示的版本号,可以回退到任何一个版本,也可通过 HEAD 来指定版本。
- HEAD 当前版本
- HEAD^ 上一个版本
- HEAD^^ 上上一个版本