Git 概览

Git 概览


2019-06-14

Git 与其他版本控制系统区别

Git 和其它版本控制系统的主要差别在于 Git 对待数据的方法。

其它大部分系统以文件变更列表的方式存储信息。 这类系统将它们保存的信息看作是一组基本文件和每个文件随时间逐步累积的差异。

Git 更像是把数据看作是对小型文件系统的一组快照。 每次你提交更新,或在 Git 中保存项目状态时,它主要对当时的全部文件制作一个快照并保存这个快照的索引。 为了高效,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。 Git 对待数据更像是一个快照流。

Git 三种状态和三个工作区域

Git 有三种状态,你的文件可能处于其中之一:

  • committed:已提交表示数据已经安全的保存在本地数据库中。
  • modified:已修改表示修改了文件,但还没保存到数据库中。
  • staged:已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。

由此引入 Git 项目的三个工作区域的概念:Git 仓库、工作目录以及暂存区域。

  • Git 仓库目录是 Git 用来保存项目的元数据和对象数据库的地方。这是 Git 中最重要的部分,从其它计算机克隆 仓库时,拷贝的就是这里的数据。

  • 工作目录是对项目的某个版本独立提取出来的内容。这些从 Git 仓库的压缩数据库中提取出来的文件,放在磁盘 上供你使用或修改。

  • 暂存区域是一个文件,保存了下次将提交的文件列表信息,一般在 Git 仓库目录中。 有时候也被称作‘索 引’,不过一般说法还是叫暂存区域。

基本的 Git 工作流程如下:

  1. 在工作目录中修改文件。
  2. 暂存文件,将文件的快照放入暂存区域。
  3. 提交更新,找到暂存区域的文件,将快照永久性存储到 Git 仓库目录。

Git 使用前的配置

使用前设置全局配置:

1
2
git config --global user.name "John Doe"
git config --global user.email johndoe@example.com

检查配置信息

1
2
git config --list
git config user.name

Git 文件的生命周期

Git 基本操作

git status 查看状态

  • Untracked files :未追踪

  • Changes to be committed :暂存状态

  • Changes not staged for commit :已追踪文件发生变化,修改后还未放入暂存区

git status -sgit status —short 可以让状态显示的更加紧凑

1
2
3
4
5
6
$ git status -s
M README
MM Rakefile
A lib/git.rb
M lib/simplegit.rb
?? LICENSE.txt

新添加的未跟踪文件前面有 ?? 标记,新添加到暂存区中的文件前面有 A 标记,修改过的文件前面有 M 标记。 你可能注意到了 M 有两个可以出现的位置,出现在右边的 M 表示该文件被修改了但是还没放入暂存区,出现在靠左边的 M 表示该文件被修改了并放入了暂存区。

.gitignore 忽略文件

文件 .gitignore 的格式规范如下:

  • 所有空行或者以 # 开头的行都会被 Git 忽略。
  • 可以使用标准的 glob 模式匹配。(glob 正则表达式类似)
  • 匹配模式可以以(/)开头防止递归。
  • 匹配模式可以以(/)结尾指定目录。
  • 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。

.gitignore 文件例子,github 上有一个关于 gitignore 的项目

1
2
3
4
5
6
7
8
9
10
11
12
# no .a files 
*.a
# but do track lib.a, even though you're ignoring .a files above
!lib.a
# only ignore the TODO file in the current directory, not subdir/TODO
/TODO
# ignore all files in the build/ directory
build/
# ignore doc/notes.txt, but not doc/server/arch.txt
doc/*.txt
# ignore all .pdf files in the doc/ directory
doc/**/*.pdf

git diff 对比修改

git diff 默认对比的工作目录中当前文件和暂存区域快照之间的差异。若要查看已暂存和已提交的版本,可以用 git diff --cached 命令。(Git 1.6.1 及更高版本还允许使用git diff --staged,效果是相同的,但更好记些。)

git commit -a 跳过使用暂存区

git commit 加上 -a 选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过git add步骤

git rm 移除文件

要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),然后提交。可以用git rm命令完成此项工作,并连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清单中了。

如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f。 这是一种安全特性,用于防止误删还没有添加到快照的数据,这样的数据不能被 Git 恢复。

想把文件从 Git 仓库中删除(亦即从暂存区域移除),但仍然希望保留在当前工作目录。此处为删除暂存区,如果

1
git rm --cached README

git mv 移动文件

1
2
3
4
5
6
$ git mv README.md README
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: README.md -> README

git mv 等于运行下面三个命令:

1
2
3
$ mv README.md README
$ git rm README.md
$ git add README

git log 查看历史提交

git log 常用命令选项

选项 说明
-p 按补丁格式显示每个更新之间的差异。
--stat 显示每次更新的文件修改统计信息。
--shortstat 只显示 –stat 中最后的行数修改添加移除统计。
--name-only 仅在提交信息后显示已修改的文件清单。
--name-status 显示新增、修改、删除的文件清单。
--abbrev-commit 仅显示 SHA-1 的前几个字符,而非所有的 40 个字符。
--relative-date 使用较短的相对时间显示(比如,“2 weeks ago”)。
--graph 显示 ASCII 图形表示的分支合并历史。
--pretty 使用其他格式显示历史提交信息。()

其中,--pretty 可用的选项包括 oneline,short,full,fuller 和 format(后跟指定格式)。

git log --pretty=format 具体内容可以查阅相关文档。

另外,git log 有许多过滤输出选项的方法,具体内容可以查阅相关文档。

git commit —amend 撤销操作

提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有 --amend 选项的提交命令尝试重新提交:

1
git commit --amend

这个命令会将暂存区中的文件提交。 如果自上次提交以来你还未做任何修改(例如,在上次提交后马上执行了此命令),那么快照会保持不变,而你所修改的只是提交信息。

例如,你提交后发现忘记了暂存某些需要的修改,可以像下面这样操作:

1
2
3
$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend

最终你只会有一个提交 - 第二次提交将代替第一次提交的结果。

取消暂存的文件

使用 git reset HEAD <file>... 来取消暂存某个文件。

撤消对文件的修改

1
git checkout -- <file>...

以上两个命令都可以通过 git status 的提示来记忆。

远程仓库的使用

查看远程仓库

origin 是 Git 给远程仓库的默认名字。

git remote -v 会显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL 。

git remote add <shortname> <url> 添加一个远程仓库。

git fetch [remote-name] 这个命令会访问远程仓库,从中拉取所有你还没有的数据。 执行完成后,你将会拥有那个远程仓库中所有分支的引用,可以随时合并或查看。

必须注意 git fetch 命令会将数据拉取到你的本地仓库 - 它并不会自动合并或修改你当前的工作。 当准备好时你必须手动将其合并入你的工作。 运行 git pull 通常会从最初克隆的服务器上抓取数据并自动尝试合并到当前所在的分支。

git push origin master 推送到远程仓库。

git remote show [remote-name] 查看远程仓库信息。

git remote rename old_name new_name 修改仓库名。

git remote rm origin 删除远程仓库。