在工作流中使用命令

  • 关键词:Git For Teams – 读书笔记

Part2 在工作流中使用命令

单人团队(独立开发者)

  • 学习目的:
    • 创建一份远程仓库的本地副本
    • 为现有的文件集初始化版本控制
    • 从空的项目目录开始创建一个新的仓库
    • 通过提交消息来检查仓库历史
    • 通过分支来隔离无关的工作
    • 在本地仓库中创建提交
    • 使用标签来高亮单个提交
    • 建立你的项目与远程代码托管系统的连接

1 基于issue的版本控制

“最擅长描述一个问题的人,最有可能能够解决它”。

工单包含以下三个主要部分:

1.问题:大致描述你想要解决的问题。

2.原因:为什么你想要做这件事(如果问题得到解决,谁将受益)?

3.质量保证测试:我将如何知道这个问题已经得到解决?

工单的另一种格式:

1.卡片:从用户的角度,大致描述这个问题。

2.对话:你想要解决的问题的细节。在可能的情况下,应该避免给出具体的解决方案。

3.确认:用户用于验证问题是否解决的步骤。

1.1 基于issue的版本控制利弊

第一反应就是使用工单的开销相对较大,或许记事本就已经足够。但继续做项目时,开始不断地忘记一些微小的想法。如果为每个想法创建一个分支,最后也会被一大堆过时的分支搞乱。

渐渐找到你使用的代码托管系统中的工单跟踪选项,记录你对软件所做的工作。至少,它会给你一些用于创建分支和跟踪代码的编号。

  • 工作流程:
    • 在你的跟踪系统中创建一个新的工单,注明这个issue编号
    • 在你的本地仓库中,使用issuenumber-description格式创建一个新的分支
    • 完成工单描述的工作(且只完成工单中描述的工作)
    • 测试你的工作,确保已经完成并且是正确的
    • 现在有了一个“杂乱”的工作目录,其中包含了新增的文件和修改过的文件
    • 将你的缓存的修改提交至仓库
    • 将你的更改推送到备用服务器上
    • 当你对你的工作完全满意时,将你的工单分支并入主分支并将修改后的分支推送到代码托管系统中
    • 再一次测试你的工作,确保没有后续问题
    • 将你的工单标记为已关闭

1.2 创建本地仓库

1.2.1 克隆已有的项目:

git clone https://gitlab.com/gitforteams/gitforteams.git

1.2.2 将已有的项目迁移至Git:

第一种是下载gitforteams-zip。你可以在任何文件夹下使用初始化命令创建一个Git仓库。

git init(初始化目录的版本控制)

将会看到Initialized empty Git repository in /…./.git/,系统并没有立即将文件加入仓库。这是git的一个特性,因为它同样允许你忽略文件,你需要主动告诉它你想要跟踪哪些文件。

如果存在相关的下一个步骤,git几乎总是会在状态(status)消息中显示有用的建议。

git status(检测仓库的当前状态)

将文件导入git分为两个步骤。这个功能允许你在工作目录中同时进行多个无关的更改。更改可以被暂存在索引的一组提交中,每组都有一个不同的提交消息。

git add –all(将仓库中所有文件添加至暂存区)

之后,你可以使用commit命令将你当前的状态保存到仓库。

git commit -m “Initial import of all projct files.”(将所有暂存的文件提交至仓库)

1.2.3 初始化空项目

从一个什么都没有的空目录开始。

mkdir empty-repository 和 cd empty-repository

git init(运行git初始化命令) 和 ls -al(确认已添加隐藏的仓库文件夹)

1.2.4 查看历史记录

log命令将按时间倒序输出仓库中提交消息的完整历史记录。

git log(使用log命令查看仓库历史记录)

对于完事的代码库上的工作,看完这些消息所需的工作量是巨大且复杂的。你可以通过–oneline参数来缩短消息,只显示消息的第一行。按Q退出。

git log –oneline(查看缩短的项目历史记录)

1.3 使用分支工作

1.3.1 列出分支

在默认情况下,会将master分支复制到你的本地仓库中,然后你可以直接在这个分支上工作。

git branch –list(列出所有分支) 或者 –all(列出所有分支)

如果你在克隆仓库的本地副本中执行这个命令,应该会同时看到你的本地分支和一个远程分支。

其中,*表示你当前正在查看(或“签出”)的分支。剩下几行以remotes/origin开头:

remotes仅表示“不在本地”。

origin是一个默认约定,表示“我的副本是从这克隆的”。

最后一部分就是分支名。

git branch –remotes(列出远程分支)

你可以访问到这些远程分支,尽管你需要在向它们提交更改之前创建你自己的副本。

1.3.2 更新远程分支列表

远程分支列表不会自动更新,因此这个列表将会随着时间而落后。使用fetch命令更新这个列表。

git fetch(获取更新的列表和所有远程分支的内容)

1.3.3 使用不同的分支

当你签出一个分支时,你更新了系统(工作区)中的可见文件,来匹配仓库中存储的版本。这个切换是通过checkout命令完成的。

git checkout –track origin/video-lessons(使用checkout命令切换分支)

旧版本的git中可能不同,如果报错,你需要升级或者运行下面的变种命令:

git checkout –track -b video-lessons origin/video-lessons(checkout -b 启用了追踪 –track)

就是说从远程仓库origin中存储的video-lessons分支上,创建了一个名为viedo-lessons的新分支。这个远程分支的本地副本可以通过origin/video-lessons访问到,而你的自己的分支副本可以通过video-lessons访问到。

1.3.4 创建新的分支

当团队规模增长时,确立团队结构的协作方式将会使你越来越多地受益。

  • 作为一个独立开发者,你或许更难明白什么时候你应该在一个不同的分支上工作。试问:
    • 如果进行得不顺利,我是否会想要完全丢弃这个想法?
    • 我正在创造的东西是否严重偏离了当前发布的软件版本?
    • 在进行发布或被软件的发布版本接受之前,我的工作是否需要经过评审?
    • 完成这项工作之前,我是否有可能切换到其他任务上去?

如果你对每个问题都持有肯定的答复,你应该考虑为你的工作创建一个新的分支。

决定什么工作需要进入新的分支的最佳方法是使用issue跟踪工具。在使用基于issue的版本控制,你的分支名应该能够反映你正在工作的工单。

可以通过checkout命令来移动到正确的分支,或者可以将你想要的父分支添加到你的命令中。

  • 创建一个新的分支:

1.git checkout master(首先签出你希望作为起点使用的分支)

2.git branch 1-process_notes(创建一个新的分支)

3.git checkout 1-process_notes(签出新分支)

或者直接从正确的基线分支创建一个新的分支,这意味着你不需要记住之前的指令来执行额外的签出步骤:

git checkout -b 1-process_notes master(从主分支上创建一个新的开发分支)

1.4 在仓库中添加更改

每次你在工作目录中进行修改时,都需要显式地将这些更改保存到你的git仓库。这个过程分为两步:暂存,然后保存到仓库。

你可以同时添加一个或多个文件名,文件名不需要是同一种类型的。

git add README.md process-diagram.png(将选中的已更改文件添加至你的git仓库)

git add branch-naming-rules.png

如果你有很多文件需要添加,而且它们还不在同一个目录下,你或许会想要使用通配符来匹配子目录中的文件,或者匹配文件名相似的文件。

git add /*(递归地添加指定路径中的所有文件)

git add *.svg(添加扩展名为.svg的所有文件)

还可以完全忽略文件名,根据git中是否已知这些文件来暂存它们。通过使用–update参数,你可以暂存git中所有已知的且在上次提交之后编辑过(或修改过)的文件:

git add –update

一次提交只会保存已添加至索引中的文件。

1.4.1 在仓库中添加部分文件修改

可以选择使用–patch参数来添加已保存的文件中的部分修改。

通过–patch添加文件的过程分成多个步骤:

你将首先初始化这个过程,然后从列表中选出一个选项,来决定如何创建你的补丁。

你将会看到一条提示,将这些修改添加至暂存区(y),或不改变这个补丁片段(hunk)(n)。

修改过的行将会以一个-(删除的行)或一个+(新增的行)开头。如果某行进行过修改,它会同时显示为被删除和被新增。

为了将这些补丁片段拆分成更小的单元,可以使用s选项来拆分这几个补丁片段。只有在两个补丁片段之间存在至少一行未修改的工作时,这个选项才会生效。

如果你希望将相邻的两行分别暂存,可编辑(e)这个补丁片段。

git add –patch filename(将选中的修改交互式地添加到你的git仓库)

1.4.2 提交部分修改

如果你只将某个文件中的部分修改添加到了暂存区,那么在查看仓库状态的时候,将会看到这个文件准备好了被提交的修改,同时也包含未被暂存的修改。

添加至暂存区的文件,在提交至仓库之前继续编辑这份文件,或者如果你只选择暂存一些补丁片段,同时使用patch参数交互地将文件添加到索引,都会出现与此相同的信息。

1.4.3 从暂存区移除文件

如果暂存区添加了太多的文件,同时想把这些修改分割为更小的提交,那么可以取消暂存你提出的修改。

git status(从暂存区移除提出的文件修改)

git reset HEAD ch05.asciidoc

如果你只想取消暂存你对文件做出的某些修改,那么还可以使用reset命令和–patch参数。

1.4.4 编写扩展提交信息

你的提交消息应该总是包含做出这个修改的原因,以及对你做出的修改的一个简要总结。为了编写一条详细的提交信息,对于你一直使用至今的单行短消息样式,你需要编写多行这样的消息。

  • 编写提交消息
    • 使用一个简短的单行消息将修改提交至仓库
    • 修补这个提交,完整地说明我在做出这个修改时在想什么

git add – all

git commit -m “CH05: Adding technical edits.”

git commit –amend

1.4.5 忽略文件

如果是Mac,会出现.DS_Store文件;如果是Linux,这可能是文本编辑器的.swp文件。如果是一个web项目,可能会包含从Sass编译出的CSS文件。

可以创建一个全局设置来忽略这些文件。

git config –global core.excludesfile ~/.gitignore(或者通配符*.swp)

另外,或许希望特定仓库忽略特定的文件或文件扩展名。在这种情况下,你的最佳选择是在仓库中添加一个额外的.gitignore文件。这样做附带的好处是,你的队友一定不会意外地将构建文件提交上来。

  • 以下几步,自定义特定仓库中应该被忽略的文件
    • 在项目根目录创建一个名为.gitignore的文件
    • 每行一个文件名,写上所有你一定不希望git添加到仓库中的文件。你可以使用确切的文件名或通配符(如*.swp)
    • 使用add和commit命令将.gitignore文件添加到你的仓库

1.5 使用标签

标签用于定位指定的提交。为了明确你想要打上标签的提交,你或许会想要同时使用log和show两个命令。log命令将会给你仓库中所有提交的列表,show命令将会显示每个提交的详细信息。

git log –oneline(最近提交的快速列表)

可以通过添加提交ID来获得这个提交开头的详细提交信息。要将输出限制到仅这个提交,请添加一个可选的参数–max-depth=,后面跟着你想要显示的记录条数。

git log fa04c30 –max-depth=1(单个提交的日志详细信息)

可以使用show命令以文本形式列出该提交中发生的修改(如果是二进制文件,比如图片,无效)。

git show fa04c30(使用show命令显示单个提交的日志消息和文本diff)

一旦你找到了想要收藏的提交,就可以通过tag命令来完成这个操作。为提交散列fa04c30创建了一个新的标签import

git tag import fa04c30

git tag(列出所有标签)

git show import(查看带标签的提交)

1.6 连接远程仓库

在git这样的去集中式版本控制系统中,没有每个人共同使用的单一仓库。我们通常会约定其中一个仓库副本享有特权(代码的官方来源)。

1.6.1 创建一个新的项目

  • gitlab注册一个账户,创建项目
  • 从新项目上,创建一个新仓库
    • mkdir my-git-for-teams
    • cd my-git-for-teams
    • git init
    • touch README.md
    • git add README.md
    • git commit -m “first commit”
    • git remote add origin git@xxx.com:xxxx/my-git-for-teams.git
    • git push -u origin master

完成了git remote add origin步骤。

如果你希望从头开始创建一个新的仓库,可以将本地仓库上传至gitlab中的新项目。

git remote add my_gitlab git@xxx.com:xxxx/my-git-for-teams.git(使用自定义的名称在本地仓库中添加远程连接)

git remote –verbose(列出连接至你当前仓库的远程仓库)

你现在可以将你的工作从任何分支推送到你的远程仓库。

1.6.3 推送你的更改

为了上传你的修改,你需要远程仓库的连接、发布到仓库的权限和你想要上传修改的分支名。

添加SSH密钥到代码托管系统。

git push(使用push命令上传分支)

在没有上游分支时,你将会得到一条错误消息:The current branch 1-process_notes has no upstream branch.

git push –set-upstream my_gitlab 1-process_notes(在上传本地分支时设置上游分支)

1.6.3 分支维护

一旦代码通过了完整的测试,就将这个工单分支并入master分支并删除本地分支和这个工单分支的远程副本。

git check master(将工单分支并入你的主分支)

git merge 1-process_notes

真正的合并,或许会弹出一个编辑器让你编写提交消息。一般都采用默认的消息,一旦工作被并入master分支,你同样应该将master分支推送到远程仓库。

git push –set-upstream my_gitlab master

修改已经被并入master分支,没有必要继续保留这个工单分支了。为了保持你的仓库整洁,你可以更进一步,现在删除这个工单分支。

git branch –delete 1-process_notes(删除这个分支的本地副本)

同样需要在远程仓库做一些清理工作。你还应该删除那些修改已并入master分支的远程分支。

git push –delete my_gitlab 1-process_notes(删除不再需要的远程分支)

当清理结束时,是时候为你的下一个想法重复这个步骤了。

1.7 命令指南

基本的Shell命令 说明
cd ~ 转到你的home目录
mkdir 创建新的目录
cd direcrtory_name 转到指定目录
ls -a 在OS X和基于Linux的系统下列出隐藏文件
dir 在Windows下列出文件
touch file_name 使用指定名称创建新的空文件
命令 说明
git clone URL 下载一份远程仓库的副本
git init 将当前目录转换成一个新的git仓库
git status 获取仓库状态报告
git add –all 将所有修改过的文件和新文件添加至仓库的暂存区
git commit -m “message” 将所有暂存的文件提交至仓库
git log 查看项目历史
git log –oneline 查看压缩过的项目历史
git branch –list 列出所有本地分支
git branch –all 列出本地和远程分支
git branch –remotes 列出所有远程分支
git checkout –track remote_name/branch 创建远程分支的副本,在本地使用
git checkout branch 切换到另一个本地分支
git checkout -b branch branch_parent 从指定分支创建一个新分支
git add filename(s) 仅暂存并准备提交指定文件
git add –patch filename 仅暂存并准备提交部分文件
git reset HEAD filename 从暂存区移除提出的文件修改
git commit –amend 使用当前暂存的修改更新之前的提交,并提供一个新的提交信息
git show commit 输出某个提交的详细信息
git tag tag commit 为某个提交对象打上标签
git tag 列出所有标签
git show tag 输出所有带标签提交的详细信息
git remote add remote_name URL 创建一个指向远程仓库的引用
git push 将当前分支上的修改上传至远程仓库
git remote –verbose 列出所有可用远程连接中fetch和push命令使用的URL
git push –set-upstream remote_name branch_local branch_remote 将本地分支的副本推送至远程服务器
git merge branch 将当前存储在另一分支的提交并入当前分支
git push –delete remote_name branch_name 在远程服务器中移除指定名称的分支