Git

Git使用分支

Git使用分支 #

BY 童仲毅( geeeeeeeeek@github

这是一篇在 原文(BY atlassian)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名( CC BY 2.5 AU)协议共享。

这份教程是 Git 分支的综合介绍。首先,我们简单讲解如何创建分支,就像请求一份新的项目历史一样。然后,我们会看到 git checkout 是如何切换分支的。最后,学习一下 git merge 是如何整合独立分支的历史。

我们已经知道,Git 分支和 SVN 分支不同。SVN 分支只被用来记录偶尔大规模的开发效果,而 Git 分支是你日常工作流中不可缺失的一部分。

git branch #

分支代表了一条独立的开发流水线。分支是我们在第二篇中讨论过的「编辑/缓存/提交」流程的抽象。你可以把它看作请求全新「工作目录、缓存区、项目历史」的一种方式。新的提交被存放在当前分支的历史中,导致了项目历史被 fork 了一份。

git branch 命令允许你创建、列出、重命名和删除分支。它不允许你切换分支或是将被 fork 的历史放回去。因此,git branchgit checkoutgit merge 这两个命令通常紧密地结合在一起使用。

git branch用法 #

git branch

列出仓库中所有分支。

git branch <branch>

创建一个名为 <branch> 的分支。不会 自动切换到那个分支去。

git branch -d <branch>

删除指定分支。这是一个安全的操作,Git 会阻止你删除包含未合并更改的分支。

git branch -D <branch>

强制删除指定分支,即使包含未合并更改。如果你希望永远删除某条开发线的所有提交,你应该用这个命令。

git branch -m <branch>

将当前分支命名为 <branch>

...

Git常见工作流比较

Git常见工作流比较 #

BY 童仲毅( geeeeeeeeek@github

这是一篇在 原文(BY atlassian)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名( CC BY 2.5 AU)协议共享。

多种多样的工作流使得在项目中实施 Git 时变得难以选择。这份教程提供了一个出发点,调查企业团队最常见的 Git 工作流。

阅读的时候,请记住工作流应该是一种规范而不是金科玉律。我们希望向你展示所有工作流,让你融会贯通,因地制宜。

这份教程讨论了下面四种工作流:

中心化的工作流 #

Git Workflows: SVN-style Workflow

过渡到分布式分版本控制系统看起来是个令人恐惧的任务,但你不必为了利用 Git 的优点而改变你现有的工作流。你的团队仍然可以用以前SVN的方式开发项目。

然而,使用 Git 来驱动你的开发工作流显示出了一些SVN没有的优点。首先,它让每个开发者都有了自己 本地 的完整项目副本。隔离的环境使得每个开发者的工作独立于项目的其它修改——他们可以在自己的本地仓库中添加提交,完全无视上游的开发,直到需要的时候。

第二,它让你接触到了 Git 鲁棒的分支和合并模型。和 SVN 不同,Git 分支被设计为一种故障安全的机制,用来在仓库之间整合代码和共享更改。

如何工作 #

和 Subversion 一样,中心化的工作流将中央仓库作为项目中所有修改的唯一入口。和 trunk 不同,默认的开发分支叫做master,所有更改都被提交到这个分支。这种工作流不需要 master 之外的其它分支。

开发者将中央仓库克隆到本地后开始工作。在他们的本地项目副本中,他们可以像SVN一样修改文件和提交更改;不过,这些新的提交被保存在 本地 ——它们和中央仓库完全隔离。这使得开发者可以将和上游的同步推迟到他们方便的时候。

为了向官方项目发布修改,开发者将他们的本地 master 分支「推送」到中央仓库。这一步等同于 svn commit,除了Git添加的是所有不在中央 master 分支上的本地提交。

Central and local repositories

管理冲突 #

中央仓库代表官方项目,因此它的提交历史应该被视作神圣不可更改的。如果开发者的本地提交和中央仓库分叉了,Git 会拒绝将他们的修改推送上去,因为这会覆盖官方提交。

Managing Conflicts

在开发者发布他们的功能之前,他们需要 fetch 更新的中央提交,在它们之上 rebase 自己的更改。这就像是「我想要在其他人的工作进展之上添加我的修改」,它会产生完美的线性历史,就像和传统的 SVN 工作流一样。

...

Git图解

Git图解 #

BY 童仲毅( geeeeeeeeek@github

这是一篇在 原文基础上演绎的文章。原作者 Mark Lodato,译者 wych。原文采用 创用 CC 姓名标示-非商业性-相同方式分享 3.0 美国授权条款授权。

此页图解 git 中的最常用命令。如果你稍微理解 git 的工作原理,这篇文章能够让你理解的更透彻。

基本用法 #

enter image description here

上面的四条命令在工作目录、stage 缓存(也叫做索引)和 commit 历史之间复制文件。

  • git add files 把工作目录中的文件加入 stage 缓存
  • git commit 把 stage 缓存生成一次 commit,并加入 commit 历史
  • git reset -- files 撤销最后一次 git add files,你也可以用 git reset 撤销所有 stage 缓存文件
  • git checkout -- files 把文件从 stage 缓存复制到工作目录,用来丢弃本地修改

你可以用 git reset -pgit checkout -pgit add -p 进入交互模式,也可以跳过 stage 缓存直接从 commit历史取出文件或者直接提交代码。

...

Git代码合并选Merge还是Rebase

Git代码合并选Merge还是Rebase #

BY 童仲毅( geeeeeeeeek@github

这是一篇在 原文(BY atlassian)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名( CC BY 2.5 AU)协议共享。

git rebase 这个命令经常被人认为是一种 Git 巫术,初学者应该避而远之。但如果使用得当的话,它能给你的团队开发省去太多烦恼。在这篇文章中,我们会比较 git rebase 和类似的 git merge 命令,找到 Git 工作流中 rebase 的所有用法。

概述 #

你要知道的第一件事是,git rebasegit merge 做的事其实是一样的。它们都被设计来将一个分支的更改并入另一个分支,只不过方式有些不同。

想象一下,你刚创建了一个专门的分支开发新功能,然后团队中另一个成员在 master 分支上添加了新的提交。这就会造成提交历史被 fork 一份,用 Git 来协作的开发者应该都很清楚。

enter image description here

现在,如果 master 中新的提交和你的工作是相关的。为了将新的提交并入你的分支,你有两个选择:merge 或 rebase。

Merge #

将 master 分支合并到 feature 分支最简单的办法就是用下面这些命令:

git checkout feature
git merge master

或者,你也可以把它们压缩在一行里。

git merge master feature

feature 分支中新的合并提交(merge commit)将两个分支的历史连在了一起。你会得到下面这样的分支结构:

...

Git代码回滚选Reset、Checkout还是Revert

Git代码回滚选Reset、Checkout还是Revert #

BY 童仲毅( geeeeeeeeek@github

这是一篇在 原文(BY atlassian)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名( CC BY 2.5 AU)协议共享。

git resetgit checkoutgit revert 是你的 Git 工具箱中最有用的一些命令。它们都用来撤销代码仓库中的某些更改,而前两个命令不仅可以作用于提交,还可以作用于特定文件。

因为它们非常相似,所以我们经常会搞混,不知道什么场景下该用哪个命令。在这篇文章中,我们会比较 git resetgit checkoutgit revert 最常见的用法。希望你在看完后能游刃有余地使用这些命令来管理你的仓库。

Git repo的主要组成

Git 仓库有三个主要组成——工作目录,缓存区和提交历史。这张图有助于理解每个命令到底产生了哪些影响。当你阅读的时候,牢记这张图。

提交层面的操作 #

你传给 git resetgit checkout 的参数决定了它们的作用域。如果你没有包含文件路径,这些操作对所有提交生效。我们这一节要探讨的就是提交层面的操作。注意,git revert 没有文件层面的操作。

Reset #

在提交层面上,reset 将一个分支的末端指向另一个提交。这可以用来移除当前分支的一些提交。比如,下面这两条命令让 hotfix 分支向后回退了两个提交。

git checkout hotfix
git reset HEAD~2

hotfix 分支末端的两个提交现在变成了悬挂提交。也就是说,下次 Git 执行垃圾回收的时候,这两个提交会被删除。换句话说,如果你想扔掉这两个提交,你可以这么做。reset 操作如下图所示:

把hotfix分支reset到HEAD~2

如果你的更改还没有共享给别人,git reset 是撤销这些更改的简单方法。当你开发一个功能的时候发现「糟糕,我做了什么?我应该重新来过!」时,reset 就像是 go-to 命令一样。

除了在当前分支上操作,你还可以通过传入这些标记来修改你的缓存区或工作目录:

  • –soft – 缓存区和工作目录都不会被改变
  • –mixed – 默认选项。缓存区和你指定的提交同步,但工作目录不受影响
  • –hard – 缓存区和工作目录都同步到你指定的提交

把这些标记想成定义 git reset 操作的作用域就容易理解多了。

...

Git log高级用法

Git log高级用法 #

BY 童仲毅( geeeeeeeeek@github

这是一篇在 原文(BY atlassian)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名( CC BY 2.5 AU)协议共享。

每一个版本控制系统的出现都是为了让你记录代码的变化。你可以看到项目的历史记录——谁贡献了什么、bug 是什么时候引入的,还可以撤回有问题的更改。但是,首先你得知道如何使用它。这也就是为什么会有 git log 这个命令。

到现在为止,你应该已经知道如何用 git log 命令来显示最基本的提交信息。但除此之外,你还可以传入各种不同的参数来获得不一样的输出。

git log 有两个高级用法:一是自定义提交的输出格式,二是过滤输出哪些提交。这两个用法合二为一,你就可以找到你项目中你需要的任何信息。

格式化 Log 输出 #

首先,这篇文章会展示几种 git log 格式化输出的例子。大多数例子只是通过标记向 git log 请求或多或少的信息。

如果你不喜欢默认的 git log 格式,你可以用 git config 的别名功能来给你想要的格式创建一个快捷方式。

Oneline #

--oneline 标记把每一个提交压缩到了一行中。它默认只显示提交ID和提交信息的第一行。git log --oneline 的输出一般是这样的:

0e25143 Merge branch 'feature'
ad8621a Fix a bug in the feature
16b36c6 Add a new feature
23ad9ad Add the initial code base

它对于获得项目的总体情况很有帮助。

...

Git 钩子:自定义你的工作流

Git 钩子:自定义你的工作流 #

BY 童仲毅( geeeeeeeeek@github

这是一篇在 原文(BY atlassian)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名( CC BY 2.5 AU)协议共享。

Git 钩子是在 Git 仓库中特定事件发生时自动运行的脚本。它可以让你自定义 Git 内部的行为,在开发周期中的关键点触发自定义的行为。

git hook

Git 钩子最常见的使用场景包括推行提交规范,根据仓库状态改变项目环境,和接入持续集成工作流。但是,因为脚本可以完全定制,你可以用 Git 钩子来自动化或者优化你开发工作流中任意部分。

在这篇文章中,我们会先简要介绍 Git 钩子是如何工作的。然后,我们会审视一些本地和远端仓库使用最流行的钩子。

Git钩子概述 #

Git 钩子是仓库中特定事件发生时 Git 自动运行的普通脚本。因此,Git 钩子安装和配置也非常容易。

钩子在本地或服务端仓库都可以部署,且只会在仓库中事件发生时被执行。在文章后面我们会具体地研究各种钩子。接下来所讲的配置对本地和服务端钩子都起作用。

安装钩子 #

钩子存在于每个 Git 仓库的 .git/hooks 目录中。当你初始化仓库时,Git 自动生成这个目录和一些示例脚本。当你观察 .git/hooks 时,你会看到下面这些文件:

applypatch-msg.sample       pre-push.sample
commit-msg.sample           pre-rebase.sample
post-update.sample          prepare-commit-msg.sample
pre-applypatch.sample       update.sample
pre-commit.sample

这里已经包含了大部分可用的钩子了,但是 .sample 拓展名防止它们默认被执行。为了安装一个钩子,你只需要去掉 .sample 拓展名。或者你要写一个新的脚本,你只需添加一个文件名和上述匹配的新文件,去掉 .sample 拓展名。

比如说,试试安装一个 prepare-commit-msg 钩子。去掉脚本的 .sample 拓展名,在文件中加上下面这两行:

#!/bin/sh

echo "# Please include a useful commit message!" > $1

钩子需要能被执行,所以如果你创建了一个新的脚本文件,你需要修改它的文件权限。比如说,为了确保 prepare-commit-msg 可执行,运行下面这个命令:

...

Git提交引用和引用日志

Git提交引用和引用日志 #

BY 童仲毅( geeeeeeeeek@github

这是一篇在 原文(BY atlassian)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名( CC BY 2.5 AU)协议共享。

提交是 Git 的精髓所在,你无时不刻不在创建和缓存提交、查看以前的提交,或者用各种Git命令在仓库间转移你的提交。大多数的命令都对同一个提交操作,而有些会接受提交的引用作为参数。比如,你可以给 git checkout 传入一个引用来查看以前的提交,或者传入一个分支名来切换到对应的分支。

引用一次提交的各种方式

知道提交的各种引用方式之后,Git 的命令就会变得更加强大。在这章中,我们研究提交的各种引用方式,来一窥 git checkoutgit branchgit push 等命令的工作原理。

我们还会学到如何使用 Git 的引用日志查看似乎已被删除的提交。

哈希字串 #

引用一个提交最直接的方式是通过 SHA-1 的哈希字串,这是每个提交唯一的 ID。你可以在 git log 的输出中找到提交的哈希字串。

commit 0c708fdec272bc4446c6cabea4f0022c2b616eba
Author: Mary Johnson <[email protected]>
Date:   Wed Jul 9 16:37:42 2014 -0500

    一些提交信息

在 Git 命令中传递时,你只需要提供足以确定那个提交的哈希子串即可。比如,你可以这样用 git show 的命令显示上面的提交:

git show 0c708f

有时,我们需要把分支、标签或者其他间接的引用转变成对应提交的哈希。git rev-parse 命令正是你需要的。下面这个命令返回 master 分支提交的哈希字串:

git rev-parse master

当你写的自定义脚本中需要将提交引用作为参数时,这个命令非常有用。你可以让 git rev-parse 帮你处理转换,而不用手动做这件事。

...

Git备忘录

Git 是一个免费的开源分布式版本控制系统,旨在快速高效地处理从小型到超大型项目的所有项目。

Git 易于学习,占用空间小,性能快如闪电。它超越了 Subversion、CVS、Perforce 和 ClearCase 等 SCM 工具,具有廉价的本地分支、方便的暂存区域和多个工作流程等功能。

– 来自git-scm的官方介绍

git是一个分布式版本控制软件,最初由林纳斯·托瓦兹创作,于2005年以GPL许可协议发布。最初目的是为了更好地管理Linux内核开发而设计。应注意的是,这与GNU Interactive Tools(一个类似Norton Commander界面的文件管理器)不同。

git最初的开发动力来自于BitKeeper和Monotone。git最初只是作为一个可以被其他前端(比如Cogito或Stgit)包装的后端而开发的,但后来git内核已经成熟到可以独立地用作版本控制。很多被广泛使用的软件项目都使用 git 进行版本控制,其中包括 Linux 内核、X.Org服务器和OLPC内核等项目的开发流程。

Git备忘录 #

git创建仓库 #

在本地初始化仓库,然后将本地仓库与一个 GitHub 上的空仓库连接起来。

$ mkdir lrepo
$ cd lrepo
$ git init
$ git remote add origin [url]

git clone一个已存在于 GitHub 上的仓库,包括所有的文件、分支和提交(commits)

$ git clone [url]

git全局配置 #

## 配置用户名
$ git config --global user.name "[name]"

## 配置邮箱
$ git config --global user.email "[email address]"

### 配置彩色输出
$ git config --global color.ui auto

git分支 #

分支是使用 Git 工作的一个重要部分。你做的任何提交都会发生在当前“checked out”到的分支上。使用 git status 查看那是哪个分支。

...

GitHub发布Release详尽指南

在开发过程中,发布 Release 是一个重要的环节,能够有效地管理软件的版本和交付。本文将详细介绍如何在 GitHub 上发布 Release,包括操作步骤、注意事项及常见问题解答。

什么是GitHub Release #

GitHub Release 是 GitHub 提供的一项功能,用于管理项目的发布版本。每一个 Release 都可以附带二进制文件、源代码压缩包以及变更日志,方便用户下载和使用。通过 Release,开发者能够清晰地展示项目的进展,并为用户提供稳定的版本。

为什么要在 GitHub 上发布 Release #

  • 版本管理:使用 Release 可以帮助开发者对项目进行有效的版本管理。
  • 便于用户下载:用户可以轻松找到适合自己的版本进行下载。
  • 信息透明:Release 说明可以让用户了解到版本更新的内容与改动。

如何在 GitHub 上发布 Release #

第一步:准备工作 #

在发布 Release 之前,需要确保你的项目已经完成了相应的功能开发和测试。

  • 确保代码稳定:确认你的代码已经经过充分测试,能够正常运行。
  • 更新文档:确保项目的文档(如 README 文件)是最新的,并且描述了新版本的主要特性。

第二步:创建 Tag #

  1. 登录到你的 GitHub 账号,进入需要发布 Release 的项目页面。
  2. 点击页面上方的 “Code” 选项卡。
  3. 在页面右侧,找到 “Releases” 链接,点击进入。
  4. 点击 “Draft a new release” 按钮。
  5. 在 “Tag version” 输入框中输入新的 Tag 名称(例如 v1.0.0)。
  6. 选择相应的基础分支(通常是 main 或 master)。

第三步:填写 Release 信息 #

在创建 Release 页面中,需要填写一些关键信息:

...