获取 GIT 仓库

通常获取 GIT 项目仓库的方式有两种

  1. 将尚未进行版本控制的本地目录转换为 GIT 仓库
  2. 从其它服务器 克隆 一个已存在的 GIT 仓库

在已有目录中初始化仓库

如果你有一个尚未进行版本控制的项目目录,想要用 GIT 控制它,那么首先需要进入该项目目录中

(一)执行如下命令初始化仓库

git init

(二)现在我们仅仅是做了一个初始化的操作,项目中的文件还没有与远程仓库关联,我们需要执行以下命令关联远程仓库

git remote add [shortname] [url]

# 示例
git remote add origin https://www.github.com/******

(三)查看关联的远程仓库

git remote

# origin

git remote -v

# origin https://github.com/******* (fetch)
# origin https://github.com/******* (push)

克隆远程仓库

git clone <url> [filename]

该方***将远程库拷贝至本地,并自动与远程库关联

基本操作

现在我们的机器上有了一个 真实项目 的 Git 仓库,并从这个仓库检出了所有文件的工作副本。通常,你会对这些文件做些修改,每当完成一个阶段的目标,想要记录时,就将他提交到仓库

工作目录下的每一个文件都不外乎这两种状态:已跟踪未跟踪

已跟踪的文件是指那些被纳入了版本控制的文件,在上一次的快照中有它们的记录,在工作了一段时间后,它们的状态可能是 未修改已修改已放入暂存区,简而言之,已跟踪的文件就是 Git 已经知道的文件

工作目录中除已跟踪文件外的其它所有文件都属于 未跟踪文件,它们既不存在于上次快照的记录中,也没有被放入暂存区

查看文件状态

查看本地仓库中的文件状态

git status

# 简略信息
git status -s

跟踪新文件

跟踪新文件,将文件添加到暂存区

git add <filename>

# 跟踪所有文件
git add *

# 通配符,跟踪 c 开头的文件
git add c*

查看修改内容

# 比较 工作区文件 和 暂存区文件 差异

git diff <filename>

# 比较 暂存区文件 和 本地仓库文件 差异

git diff --staged <filename>

# 比较 工作区文件 和 本地仓库文件 差异
git diff HEAD <filename>

提交更新

现在暂存区的文件已经准备就绪,可以提交了。在此之前,请务必确认还有没有已修改或者新建的文件尚未添加到暂存区中,否则提交的时候不会记录这些尚未暂存的变化,这些已修改但未暂存的文件只会保留在本地磁盘

所以,每次提交前,先使用 git status 看下,你所需要的文件是不是都已经暂存起来了,然后再运行提交命令!

# 常用
git commit -m ""

# 将已跟踪文件提交到本地仓库,而无需进行 git add
git commit -am ""

# 追加提交 将新修改的代码追加到前一次 commit
git add new.py
git commit --amend

# 修改前一次提交信息
git commit --amend -m "***"

查看提交历史

在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。完成这个任务最简单而有效的工具是 git log 命令

当你在项目中运行 git log 命令时,可以看到下面的输出

不传入任何参数的默认情况下,git log 会按时间先后顺序列出所有的提交,最近的更新排在上面。正如你所看到的,这个命令会列出每个提交的 SHA-1 校验、作者的名字、电子邮件地址、提交时间以及提交说明

git log 有许多选项可以帮助你搜寻你所要找的提交,下面介绍几个常用的选项

(1) git log -p

其中一个比较有用的选项是 -p ,它会显示每次提交所引入的差异 ( 按补丁的格式输出 ),你也可以限制显示的日志条目数量,例如使用 -2 选项来只显示最近两次的提交

git log -p -2

(2) git log --stat

显示每次提交的文件修改统计信息,可以使用 --stat 选项,该选项在每次提交的下面列出所有被修改过的文件,哪些行被移除或是添加了,在每次提交的最后还有一个总结

(3) git log --pretty=format

可以定制记录的显示格式,这样的输出对后期提取分期格外有用,因为你知道输出的格式不会随着 Git 的更新而发生变化

git log --pretty=format:"%h - %an,%ar : %s"

常用选项:

选项 描述
%H 提交的完整哈希值
%h 提交的简写哈希值
%T 树的完整哈希值
%t 树的简写哈希值
%P 父提交的完整哈希值
%p 父提交的简写哈希值
%an 作者名字
%ae 作者的电子邮件地址
%ad 作者修订日期(可以使用 --data=选项 定制格式)
%ar 作者修订日期,按多久以前的方式显示
%cn 提交者的名字
%ce 提交者的电子邮件地址
%cd 提交日期
%cr 提交日期(距今多长时间)
%s 提交说明

(4) git log … --graph

在日志旁以 ASCII 图形显示分支与合并历史

(5) git reflog

当你回退到某个版本,突然后悔了,会要恢复到新版本,但是找不到新版本的 commit id 怎么办?
在 GIT 中,总是有后悔药可以吃的,Git 提供了一个命令 git reflog 用来记录你的每一次命令,
可以非常方便地找到你的 commit id

(6) 筛选日志

# 显示 4-12号之前的提交
git log --before="2020-04-12"

# 显示文件内容中 添加或删除了 某字符串的提交
git log -S examples

# 显示提交说明中包含 某字符串的提交
git log --grep="fix"
选项 描述
-<n> 仅显示最近的 n 条提交
--since,--after 仅显示指定时间之后的提交
--until,--before 仅显示指定之间之前的提交
--author 仅显示匹配字符串的作者的提交
--commiter 仅显示匹配字符串的提交者的提交
--grep 仅显示提交说明中包含指定字符串的提交
-S 仅显示提交或删除内容匹配指定字符串的提交

撤销操作

工作区文件撤销:

  • git restore <file>..
  • git checkout -- <file>..

暂存区文件撤销:

  • git reset HEAD <file>..
  • git restore --staged <file>..

已提交未push:

  • git reset --hard [版本号,一串哈希值]

已提交已push:

  • git revert [版本号]

回滚操作

(1) 回滚单个文件

git checkout [版本号] – file1,file2

(2) 回滚本地仓库

git reset --hard [版本号,一串哈希值]

标签管理

发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。所以,标签也是版本库的一个快照

Git的标签虽然时版本库的快照,但其实它就是指向某个 commit 的指针,所以,创建和删除标签都是瞬间完成的

Git 有 commit,为什么还要引入 tag?

Q : 请把上周一的版本打包发布,commit号是 65a84d3…
A : 一串乱七八糟的数字不好找

如果换一个办法:

Q : 请把上周一的版本打包发布,版本号是 v1.2
A : 好的,按照 tag v1.2 查找 commit 就行

所以,tag就是一个让人容易记住的有意义的名字,它跟某个 commit 绑定在一起

  • 查看标签

    # 查看所有标签
    git tag
    
    # 查看标签信息
    git show <tagname>
    
  • 创建标签

    # 打标签, 默认打在最新提交的 commit
    git tag <name>
    
    # 对指定版本打标签
    git tag <name> <id>
    
    # 创建带说明文字的标签, 使用 git show 可以看到说明文字
    git tag -a <name> -m <msg>
    
  • 删除标签

    # 删除本地标签
    git tag -d <tagname>
    
    # 删除远程标签, 先删除本地标签,然后执行如下命令
    git push origin :refs/tags/<tagname>
    

创建的标签都只存储在本地,不会自动推送到远程,如果要推送标签到远程,可使用如下命令:

  • 推送标签

    # 推送指定标签
    git push origin <tagname>
    
    # 推送全部标签
    git push origin --tags