Udacity Git & Github

Git

  • git init
    在当前目录下创建新的空仓库。

  • git clone $ git clone
    创建一个与现有仓库完全相同的副本。

  • git status
    显示仓库的当前状态。

  • git log 显示仓库commit信息
    git log --oneline 简略显示信息
    git log --stat 显示修改信息摘要
    git log -p 显示修改的详细信息

  • git show
    仅显示一个commit

  • git add $ git add
    将文件从工作目录移到暂存区

  • git commit
    取出暂存区的文件并保存到仓库中

  • git diff
    查看已经执行但是尚未 commit 的更改

  • .gitignore 文件
    告诉 git 不应跟踪的文件。该文件应该放在 .git 目录所在的目录

  • git tag $ git tag -a beta
    标记特定的 commit 。当添加新的 commit 时,标签不会移动。

  • git branch 管理 git 中的分支,列出所有分支
    git branch footer-fix 5bfe5e7 创建新的"footer-fix"分支
    git branch -d footer-fix 删除"footer-fix"分支

  • git checkout 切换分支
    git checkout -b richards-branch-for-awesome-changes 创建新分支 -b选项

  • git log --oneline --graph --all
    查看所有分支

  • git merge $ git merge
    合并 git 分支

  • 合并冲突指示符解释
    编辑器具有以下合并冲突指示符:
    "<<<<<<< HEAD" 此行下方的所有内容(直到下个指示符)显示了当前分支上的行
    "||||||| merged common ancestors" 此行下方的所有内容(直到下个指示符)显示了原始行的内容
    "=======" 表示原始行内容的结束位置,之后的所有行(直到下个指示符)是被合并的当前分支上的行的内容
    ">>>>>>> heading-update" 是要被合并的分支上的行结束指示符

  • git commit --amend 向 commit 中添加忘记的文件
    添加忘记包含的文件(或文件更改)。假设你更新了整个网站的导航链接颜色。commit 了该更改,并以为完事了。但是后来发现深藏在页面上的一个特殊导航链接没有新的颜色。你可以执行新的 commit 并更新该链接的颜色,但是这样就会出现两个 commit 执行完全相同的任务(更改链接颜色)。
    相反,你可以修改最后一个 commit(更新所有其他链接颜色的 commit)以包含这个忘记的链接。要包含忘记的链接,只需:编辑文件、保存文件、暂存文件、运行 git commit --amend。
    你对必要的 CSS 和/或 HTML 文件作出了更改,以便修正被遗忘的链接样式,然后保存所有被修改的文件,并使用 git add 暂存所有被修改的文件(就像要提交新的 commit 那样!),但是你可以运行 git commit --amend 来更新最近的 commit,而不是创建新的 commit。

  • git revert $ git revert
    还原之前创建的 commit,通常会用到祖先引用来指代之前的 commit,将 HEAD 和当前分支指针移到引用的 commit。
    --hard 选项清除 commit
    --soft 选项将 commit 的更改移至暂存区
    --mixed 选项取消暂存已被 commit 的更改

  • commit索引
    你已经知道可以使用 SHA、标签、分支和特殊的 HEAD 指针引用 commit。有时候这些并不足够,你可能需要引用相对于另一个 commit 的 commit。例如,有时候你需要告诉 git 调用当前 commit 的前一个 commit,或者是前两个 commit。我们可以使用特殊的“祖先引用”字符来告诉 git 这些相对引用。这些字符为:
    ^ – 表示父 commit
    ~ – 表示第一个父 commit
    我们可以通过以下方式引用之前的 commit:
    父 commit – 以下内容表示当前 commit 的父 commit
    HEAD^
    HEAD~
    HEAD~1
    祖父 commit – 以下内容表示当前 commit 的祖父 commit
    HEAD^^
    HEAD~2
    曾祖父 commit – 以下内容表示当前 commit 的曾祖父 commit
    HEAD^^^
    HEAD~3
    ^ 和 ~ 的区别主要体现在通过合并而创建的 commit 中。合并 commit 具有两个父级。对于合并 commit,^ 引用用来表示第一个父 commit,而 ^2 表示第二个父 commit。第一个父 commit 是当你运行 git merge 时所处的分支,而第二个父 commit 是被合并的分支。


Github

  • git remote $ git remote add repo-on-GitHub URL
    连接到多个不同的远程仓库。简写名是用于指代远程仓库位置的名称。通常该位置为 URL,但也可能是同一台计算机上的文件路径。
    git remote add 添加到新的远程仓库的连接。
    git remote -v 查看远程仓库与连接之间的详细信息。

  • git push $ git push origin master
    从本地仓库向远程仓库推送 commit,包括仓库名和分支名 。

  • git pull $ git pull origin master
    在本地仓库拉取远程仓库更改。
    在运行 git pull 时,会发生以下活动:
    远程分支上的 commit 会被复制到本地仓库
    本地跟踪分支(origin/master)移到指向最新的 commit
    本地跟踪分支(origin/master)合并到本地分支(master)

  • git fetch $ git fetch origin master
    获取远程更改,检索 commit 和移动跟踪分支。它不会将本地分支与跟踪分支合并。

  • git shortlog
    按作者对 commit 分组,显示按字母顺序排序的人名列表,以及他们对应的提交说明。
    $ git shortlog -s -n 如果我们只想看到每个开发者的 commit 数量,我们可以添加几个选项:用 -s 仅显示 commit 的数量(而不是每个 commit 的消息),以及用 -n 来按数量排序(而不是按作者姓名的字母顺序)。

  • git log --author="Richard Kalehoff" 使用 --author 选项筛选 commit
    git log --grep="border radius issue in Safari" 使用 --grep 选项筛选 commit

Github 项目合作

合作规范
  • 在开始任何工作之前,确保阅读项目的 CONTRIBUTING.md 文件。
  • 接下来,查看项目的 GitHub 问题
  • 查看现有的问题,看是否有哪些内容类似于你想贡献的更改
  • 如有必要,创建一个新的 Issue
  • 与项目维护者交流你想要做出的更改
  • 当开始开发后,将所有工作 commit 到特性分支上;
    不要在主分支上工作;
    确保给特性分支赋予一个清晰、描述性的名称;
  • 编写 commit 的一般最佳实践;
    频繁少量 commit;
    使用清晰、具有描述性的提交说明;
    必要情况下,更新 README 文件。
申请推送 Pull Request

Pull Request 是让源仓库拉取你的 commit,并融合在其项目中的请求。要创建 Pull Request,你需要完成一些操作:

  • 你必须 fork 源仓库
  • 将你的 fork 克隆到你的计算机
  • 进行一些 commit(最好是在特性分支上!)
  • 将 commit 推送回你的 fork
  • 创建一个新的 Pull Request,并选择包含你的新 commit 的分支

压制commit

git rebase 命令可以用来做很多事情。

交互式 rebase $ git rebase -i

$ git rebase -i HEAD~3
交互式地将 commit 变基到我们当前所在的 commit 向前三个的 commit

在 commit 的交互式列表中,所有 commit 都以 pick 开头,但你可以使用其他命令(reword、edit、squash、fixup、exec 和 drop)进行变换。

建议在变基之前创建一个备份(backup)分支,这样便能很容易返回到之前的状态。如果你对变基的结果满意,则可以删除 backup 分支!

rebase 命令
  • 使用 p 或 pick – 使 commit 保持原样
  • 使用 r 或 reword – 保留 commit 的内容,但修改 commit 说明
  • 使用 e 或 edit – 保留 commit 的内容,但先不要执行 commit,以便:
    添加新内容或文件
    删除内容或文件
    修改即将 commit 的内容
  • 使用 s 或 squash – 将此 commit 的更改结合到之前的 commit 中(列表中位于其上面的 commit )
  • 使用 f 或 fixup – 将此 commit 的更改结合到前一个 commit 中,但删除提交说明
  • 使用 x 或 exec – 运行 shell 命令
  • 使用 d 或 drop – 删除 commit
何时变基

git rebase 命令非常强大。它可以帮助你编辑提交说明、重新排序 commit、合并 commit 等,真的是一款非常强大的工具。现在的问题是"应该何时进行变基?"。

每当你对 commit 进行变基,Git 将为每个 commit 创建一个新的 SHA!这有很大的影响。对于 Git,SHA 为 commit 的标识符,因此不同的标识符代表着不同的 commit,无论内容是否发生了变化。

如果你已推送了你想进行变基的 commit,则不应变基。如果你在与其他开发者协作,那么他们可能已经在使用你推送的 commit。如果你随后使用 git rebase 来进行更改,并强行推送 commit,则其他开发者现在将无法与远程仓库同步。他们需要对自己的 Git 仓库进行一些复杂的手术,使它们的仓库回到工作状态……甚至可能连这一点都做不了;他们可能得抛弃之前的所有工作,使用你新变基过且强制推送的 commit 重新开始。


通用术语

版本控制系统 / 源代码管理器

版本控制系统(简称 VCS)是一个管理源代码不同版本的工具。源代码管理器(简称 SCM)是版本控制系统的另一个名称。

Git 是一个 SCM(因此也是 VCS!)。Git 网站的 URL 是 https://git-scm.com/ (注意它的域名中直接包含“SCM”!)。

提交(Commit)

Git 将数据看做微型文件系统的一组快照。每次 commit(在 Git 中保持项目状态),它都对文件当时的状况拍照,并存储对该快照的引用。你可以将其看做游戏中的保存点,它会保存项目的文件和关于文件的所有信息。

你在 Git 中的所有操作都是帮助你进行 commit,因此 commit 是 Git 中的基本单位。

仓库(Repository / repo)

仓库是一个包含项目内容以及几个文件(在 Mac OS X 上默认地处于隐藏状态)的目录,用来与 Git 进行通信。仓库可以存储在本地,或作为远程副本存储在其他计算机上。仓库是由 commit 构成的。

工作目录 / 工作区(Working Directory)

工作目录是你在计算机的文件系统中看到的文件。当你在代码编辑器中打开项目文件时,你是在工作目录中处理文件。

与这些文件形成对比的是保持在仓库中(在 commit 中!)的文件。

在使用 Git 时,工作目录与命令行工具的 current working directory (当前工作目录)不一样,后者是 shell 当前正在查看的目录。

检出(Checkout)

检出是指将仓库中的内容复制到工作目录下。

暂存区 / 暂存索引 / 索引(Staging Area / Staging Index / Index)

Git 目录下的一个文件,存储的是即将进入下个 commit 内容的信息。可以将暂存区看做准备工作台,Git 将在此区域获取下个 commit。暂存索引中的文件是准备添加到仓库中的文件。

SHA

SHA 是每个 commit 的 ID 编号。以下是 commit 的 SHA 示例:e2adf8ae3e2e4ed40add75cc44cf9d0a869afeb6

它是一个长 40 个字符的字符串(由 0–9 和 a–f 组成),并根据 Git 中的文件或目录结构的内容计算得出。SHA 的全称是"Secure Hash Algorithm"(安全哈希算法)。如果你想了解哈希算法,请参阅我们的计算机科学入门课程。

分支(Branch)

分支是从主开发流程中分支出来的新的开发流程。这种分支开发流程可以在不更改主流程的情况下继续延伸下去。

回到之前关于游戏保存点的示例,你可以将分支看做在游戏中设立保存点后,尝试一个有风险的招式。如果有风险的招式不奏效,则回到保存的位置。令分支非常强大的关键之处是你可以在一个分支上设定保存点,然后切换到另一个分支并继续设定保存点。

了解日志内容

如果你不习惯在命令行上使用分页器,那么 less(英) 用起来会比较奇怪。以下是一些实用技巧:

  • 向下滚动,按下

  • j 一次向下移动一行

  • d 按照一半的屏幕幅面移动

  • f 按照整个屏幕幅面移动

  • 向上滚动,按下

  • k 一次向上移动一行

  • u 按照一半的屏幕幅面移动

  • b 按照整个屏幕幅面移动

  • 按下 q 可以退出日志(返回普通的命令提示符)

良好的提交说明

我们来思考一个问题:

如何编写良好的提交说明?为何要编写好的提交说明?

问的好!花点时间编写良好的提交说明,再怎么强调这一点都不为过。

何为好的提交说明呢?问的好,很多人发表过关于这一问题的文章,比如: 如何编写 Git Commit Message - 英|译文 、Commit message 和 Change log 编写指南。在编写好的提交说明时,需要注意以下几个事项:

建议

  • 消息篇幅简短(少于 60 个字符)

  • 解释提交的作用(不是如何更改或为何更改!)

禁忌

  • 请勿解释为何做出了这些更改(下文会深入讲解这一点)

  • 请勿解释如何进行了更改(这是 git log -p 的目的!)

  • 请勿使用单词"and"

  • 如果你必须使用 "and",则你的提交说明可能进行了太多的更改,将这些更改拆分为独立的 commit

  • 例如 "make the background color pink and increase the size of the sidebar"

在编写提交说明时,我喜欢用以下短语造句:"This commit will…"。你可以补充完整该句子并作为提交说明使用。

通配符速成课程

假设你向项目中添加了 50 个图片,但是希望 git 忽略所有这些图片。这样的话,是否需要将每个文件名都列在 .gitignore 文件中呢?当然不用了,要不然太可怕了!相反,你可以采用一个叫做 通配符(英 的概念。

通配符允许你使用特殊的字符来表示某些格式/字符。在 .gitignore 文件中,你可以使用:

  • 空白行作为空格
  • # - 将行标记为注释
  • * - 与 0 个或多个字符匹配
  • ? - 与 1 个字符匹配
  • [abc] - 与 a、b 或 c 匹配
  • ** - 与嵌套目录匹配 - a/**/z 与以下项匹配
    • a/z
    • a/b/z
    • a/b/c/z

因此如果所有 50 个图片都是 JPEG 图片,并且位于"samples"文件夹中,那么我们可以向 .gitignore 中添加以下行,使 git 忽略所有这 50 个图片。

samples/*.jpg

你可能感兴趣的:(Udacity Git & Github)