<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Git配方 on GitFAQ中文网</title><link>http://www.gitfaq.cn/docs/git-recipes/</link><description>Recent content in Git配方 on GitFAQ中文网</description><generator>Hugo</generator><language>zh</language><copyright>[black8](https://0x8.net/)</copyright><lastBuildDate>Mon, 26 Oct 2026 17:16:02 +0800</lastBuildDate><atom:link href="http://www.gitfaq.cn/docs/git-recipes/index.xml" rel="self" type="application/rss+xml"/><item><title>什么是 Git？</title><link>http://www.gitfaq.cn/docs/git-recipes/What-is-Git/</link><pubDate>Sun, 24 Nov 2024 16:50:12 +0800</pubDate><guid>http://www.gitfaq.cn/docs/git-recipes/What-is-Git/</guid><description>&lt;h1 id="什么是-git"&gt;什么是 Git？&lt;a class="anchor" href="#%e4%bb%80%e4%b9%88%e6%98%af-git" aria-label="Link"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;blockquote class=''&gt;&#10;&lt;p&gt;✍️ &lt;a href="https://github.com/houkensjtu"&gt;houkensjtu&lt;/a&gt; | &lt;a href="https://github.com/geeeeeeeeek"&gt;童仲毅&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;©️ 本文演绎自 Atlassian 编写的 &lt;a href="https://www.atlassian.com/git/tutorials/what-is-git"&gt;&lt;em&gt;What is Git&lt;/em&gt;&lt;/a&gt;。页面上所有内容采用知识共享-署名（&lt;a href="http://creativecommons.org/licenses/by/2.5/au/deed.zh"&gt;CC BY 2.5 AU&lt;/a&gt;）许可协议。&lt;/p&gt;&#10;&lt;/blockquote&gt;&lt;p&gt;到目前为止，Git 是世界上使用最为广泛的现代化版本控制系统。Git 最初由 Linux 系统内核的作者 Linus Torvalds 在 2005 年开始开发，目前已经是一个持续维护的成熟开源项目。如今，大量软件项目依赖 Git 进行版本管理，其中既有开源软件，也有商业软件。Git 在很多操作系统和集成开发环境（IDE）上都表现良好。绝大多数软件开发者或多或少都使用过 Git。&lt;/p&gt;&#10;&lt;p&gt;Git 是分布式版本管理（DVCS）的一种。CVS 和 Subversion（SVN）等集中式的版本管理软件将完整的版本历史存放在同一个地方。而在 Git 中，每个开发者的代码仓库都包含了所有变更历史。&lt;/p&gt;&#10;&lt;p&gt;除了分布式之外，Git 在设计之初也考虑了性能、安全性和灵活性。&lt;/p&gt;&#10;&lt;h3 id="高性能"&gt;高性能&lt;a class="anchor" href="#%e9%ab%98%e6%80%a7%e8%83%bd" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;p&gt;Git 的底层性能相较于其他版本管理软件有强大的优势。提交修改、创建分支、合并分支和比较版本都针对性能进行了优化。Git 中实现的算法利用了现实中代码树的特点以及它们被修改和访问的常见模式。&lt;/p&gt;&#10;&lt;p&gt;不同于某些版本管理软件，Git 在决定文件树的储存和版本历史时，不会被文件名的变化所愚弄——Git 关注的是文件的内容本身。毕竟，代码文件经常会被重命名、拆分和重新编排。Git 仓库中的文件对象通过差分编码（delta encoding，仅保存代码修改的差分）和压缩技术储存，并且直接保存文件夹中的内容和版本控制元数据。&lt;/p&gt;&#10;&lt;p&gt;分布式架构也给 Git 带来了巨大的性能优势。&lt;/p&gt;&#10;&lt;p&gt;比如说，有一名开发成员 Alice 修改了代码，添加了一些准备在 2.0 版本中发布的功能，然后提交了这些修改及其描述。随后，她又编写并提交了另一个新功能。很自然地，这两次修改是版本历史中两份独立的工作。Alice 又切换到了 1.3 版本的分支，修复了一个只影响这个旧版本的 bug。这次修复的目的是为了让团队在 2.0 版本还没有完成之前，发布一个 1.3.1 版本来解决旧版本中的一些 bug。Alice 可以立刻回到 2.0 版本分支，继续新功能开发。这一切都不需要网络连接，非常快速可靠，甚至可以在飞机中完成。当她准备好将这些单独提交的更改发送到远程仓库时，她只需要一个“推送”（push）命令。&lt;/p&gt;&#10;&lt;h3 id="安全"&gt;安全&lt;a class="anchor" href="#%e5%ae%89%e5%85%a8" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;p&gt;Git 设计时就把托管代码的完好性作为重中之重。文件内容以及文件、目录、版本、标签和提交的关联，都通过安全的加密哈希校验算法（SHA1）保护。这可以避免代码和修改历史被不小心或者恶意改变，并且保证修改历史完全可追迹。&lt;/p&gt;</description></item><item><title>Git简易指南</title><link>http://www.gitfaq.cn/docs/git-recipes/Easy-Guide-to-Git/</link><pubDate>Sun, 24 Nov 2024 16:50:12 +0800</pubDate><guid>http://www.gitfaq.cn/docs/git-recipes/Easy-Guide-to-Git/</guid><description>&lt;h1 id="git简易指南"&gt;Git简易指南&lt;a class="anchor" href="#git%e7%ae%80%e6%98%93%e6%8c%87%e5%8d%97" aria-label="Link"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;blockquote class=''&gt;&#10;&lt;p&gt;BY 童仲毅（&lt;a href="https://gitfaq.cn/docs/git-recipes/"&gt;geeeeeeeeek@github&lt;/a&gt;）&lt;/p&gt;&#10;&lt;p&gt;除非另行注明，页面上所有内容采用知识共享-署名（&lt;a href="http://creativecommons.org/licenses/by/2.5/au/deed.zh"&gt;CC BY 2.5 AU&lt;/a&gt;）协议共享。&lt;a href="https://github.com/rogerdudler/git-guide/"&gt;git-guide&lt;/a&gt; 项目对本文亦有贡献。&lt;/p&gt;&#10;&lt;/blockquote&gt;&lt;p&gt;这节是完全面向入门者的，我假设你从零开始创建一个项目并且想用 Git 来进行版本控制，因此本文会避开分支这些相对复杂的概念。&lt;/p&gt;&#10;&lt;p&gt;在这节中，我会介绍如何在你的个人项目中使用 Git，我们会讨论 Git 最基本的操作——如何初始化你的项目，如何管理新的或者已有的文件，如何在远端仓库中储存你的代码。&lt;/p&gt;&#10;&lt;h2 id="安装-git"&gt;安装 Git&lt;a class="anchor" href="#%e5%ae%89%e8%a3%85-git" aria-label="Link"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Mac 用户：Xcode Command Line Tools 自带 Git（&lt;code&gt;xcode-select --install&lt;/code&gt;）&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Linux 用户：&lt;code&gt;sudo apt-get install git&lt;/code&gt;&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Windows 用户：下载 &lt;a href="http://www.gitfaq.cn/download_git/"&gt;Git SCM&lt;/a&gt;&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;- 对于 Windows 用户，安装后如果希望在全局的 cmd 中使用 Git，需要把 git.exe 加入 PATH 环境变量中，或在 Git Bash 中使用 Git。&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="检出仓库"&gt;检出仓库&lt;a class="anchor" href="#%e6%a3%80%e5%87%ba%e4%bb%93%e5%ba%93" aria-label="Link"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;执行如下命令以创建一个本地仓库的克隆版本：&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;git clone /path/to/repository&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;如果是远端服务器上的仓库，你的命令会是这个样子：&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;git clone username@host:/path/to/repository&lt;/code&gt; （通过 SSH）&lt;/p&gt;&#10;&lt;p&gt;或者：&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;git clone https:/path/to/repository.git&lt;/code&gt; （通过 https）&lt;/p&gt;&#10;&lt;p&gt;比如说 &lt;code&gt;git clone https://github.com/geeeeeeeeek/git-recipes.git&lt;/code&gt; 可以将 git 教程 clone 到你指定的目录。&lt;/p&gt;</description></item><item><title>Git创建代码仓库</title><link>http://www.gitfaq.cn/docs/git-recipes/Git-creates-a-code-repository/</link><pubDate>Sun, 24 Nov 2024 16:50:12 +0800</pubDate><guid>http://www.gitfaq.cn/docs/git-recipes/Git-creates-a-code-repository/</guid><description>&lt;h1 id="git创建代码仓库"&gt;Git创建代码仓库&lt;a class="anchor" href="#git%e5%88%9b%e5%bb%ba%e4%bb%a3%e7%a0%81%e4%bb%93%e5%ba%93" aria-label="Link"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;blockquote class=''&gt;&#10;&lt;p&gt;BY 童仲毅(&lt;a href="https://gitfaq.cn/docs/git-recipes/"&gt;geeeeeeeeek@github&lt;/a&gt;)&lt;/p&gt;&#10;&lt;p&gt;这是一篇在&lt;a href="https://www.atlassian.com/git/tutorials/setting-up-a-repository"&gt;原文(BY atlassian)&lt;/a&gt;基础上演绎的译文。除非另行注明，页面上所有内容采用知识共享-署名(&lt;a href="http://creativecommons.org/licenses/by/2.5/au/deed.zh"&gt;CC BY 2.5 AU&lt;/a&gt;)协议共享。&lt;/p&gt;&#10;&lt;/blockquote&gt;&lt;p&gt;这一章简要地带你了解一些最重要的 Git 命令。在这节中，我会向你介绍开始一个新的版本控制项目需要的所有工具，后面的几节包含了你每天都会用到的Git操作。&lt;/p&gt;&#10;&lt;p&gt;在这节之后，你应该能够创建一个新的 Git 仓库，缓存你的项目以免丢失，以及查看你项目的历史。&lt;/p&gt;&#10;&lt;h2 id="git-init"&gt;git init&lt;a class="anchor" href="#git-init" aria-label="Link"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;git init&lt;/code&gt; 命令创建一个新的 Git 仓库。它用来将已存在但还没有版本控制的项目转换成一个 Git 仓库，或者创建一个空的新仓库。大多数Git命令在未初始化的仓库中都是无法使用的，所以这就是你运行新项目的第一个命令了。&lt;/p&gt;&#10;&lt;p&gt;运行 &lt;code&gt;git init&lt;/code&gt; 命令会在你项目的根目录下创建一个新的 &lt;code&gt;.git&lt;/code&gt; 目录，其中包含了你项目必需的所有元数据。除了 &lt;code&gt;.git&lt;/code&gt; 目录之外，已经存在的项目不会被改变（就像 SVN 一样，Git 不强制每个子目录中都有一个 &lt;code&gt;.git&lt;/code&gt; 目录）。&lt;/p&gt;&#10;&lt;h3 id="git-init用法"&gt;&lt;code&gt;git init&lt;/code&gt;用法&lt;a class="anchor" href="#git-init%e7%94%a8%e6%b3%95" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git init&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;将当前的目录转换成一个 Git 仓库。它在当前的目录下增加了一个 &lt;code&gt;.git&lt;/code&gt; 目录，于是就可以开始记录项目版本了。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git init &amp;lt;directory&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在指定目录创建一个空的 Git 仓库。运行这个命令会创建一个名为 &lt;code&gt;directory&lt;/code&gt;，只包含 &lt;code&gt;.git&lt;/code&gt; 子目录的空目录。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git init --bare &amp;lt;directory&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;初始化一个裸的 Git 仓库，但是忽略工作目录。共享的仓库应该总是用 &lt;code&gt;--bare&lt;/code&gt; 标记创建（见下面的讨论）。一般来说，用 &lt;code&gt;—bare&lt;/code&gt; 标记初始化的仓库以 &lt;code&gt;.git&lt;/code&gt; 结尾。比如，一个叫&lt;code&gt;my-project&lt;/code&gt;的仓库，它的空版本应该保存在 &lt;code&gt;my-project.git&lt;/code&gt; 目录下。&lt;/p&gt;&#10;&lt;h3 id="讨论"&gt;讨论&lt;a class="anchor" href="#%e8%ae%a8%e8%ae%ba" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;p&gt;和 SVN 相比，&lt;code&gt;git init&lt;/code&gt; 命令是一个创建新的版本控制项目非常简单的途径。Git 不需要你创建仓库，导入文件，检查正在修改的拷贝。你只需要 &lt;code&gt;cd&lt;/code&gt; 到你的项目目录下，运行 &lt;code&gt;git init&lt;/code&gt;，你就有了一个功能强大的 Git 仓库。&lt;/p&gt;</description></item><item><title>Git保存更改</title><link>http://www.gitfaq.cn/docs/git-recipes/Git-saves-the-changes/</link><pubDate>Sun, 24 Nov 2024 16:50:12 +0800</pubDate><guid>http://www.gitfaq.cn/docs/git-recipes/Git-saves-the-changes/</guid><description>&lt;h1 id="git保存更改"&gt;Git保存更改&lt;a class="anchor" href="#git%e4%bf%9d%e5%ad%98%e6%9b%b4%e6%94%b9" aria-label="Link"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;p&gt;&lt;img src="http://www.gitfaq.cn/imgs/hero.svg" alt="Saving changes" /&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;em&gt;&lt;strong&gt;git add / git commit / git diff / git stash / .gitignore&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;&#10;&lt;blockquote class=''&gt;&#10;&lt;p&gt;✍️ &lt;a href="https://github.com/geeeeeeeeek"&gt;童仲毅&lt;/a&gt; | ⏳ 2018 年 10 月 26 日（部分章节未更新）&lt;/p&gt;&#10;&lt;p&gt;©️ 本文演绎自 Atlassian 编写的 &lt;a href="https://www.atlassian.com/git/tutorials/saving-changes"&gt;&lt;em&gt;Saving Changes&lt;/em&gt;&lt;/a&gt;。页面上所有内容采用知识共享-署名（&lt;a href="http://creativecommons.org/licenses/by/2.5/au/deed.zh"&gt;CC BY 2.5 AU&lt;/a&gt;）许可协议。&lt;/p&gt;&#10;&lt;/blockquote&gt;&lt;p&gt;“保存”这个概念在 Git 等版本控制系统和 Word 等文本编辑应用中不太一样。传统软件里的“保存”在 Git 里被叫做“提交”（commit）。 我们常说的的保存可以理解成在文件系统中覆盖一个已有的文件或者创建一个新的文件。而在 Git 中，提交这个操作作用于若干个文件和目录。&lt;/p&gt;&#10;&lt;p&gt;在 Git 和 SVN 里保存更改也不一样。SVN 提交或检入（check-in）将会推送到远端的中央服务器。也就是说 SVN 的提交需要联网才能完全“保存”项目更改。Git 提交可以在本地完成，然后再使用&lt;code&gt;git push -u origin master&lt;/code&gt;命令推送到远端服务器。这两种方法的区别体现了两种架构设计的本质区别。Git 是一个分布式的应用，而 SVN 是一个中心化的应用。分布式应用一般来说更可靠，因为它们不存在中央服务器这样的单点故障。&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;git add&lt;/code&gt;、&lt;code&gt;git status&lt;/code&gt;和&lt;code&gt;git commit&lt;/code&gt;这三个命令通常一起使用，将 Git 项目当前的状态保存成一份快照。&lt;/p&gt;&#10;&lt;p&gt;Git 还有另一个保存机制：“储藏”（stash）。储藏是一个临时的储存区域，保存还没准备好提交的更改。储藏操作作用于工作目录，三个文件树中的第一棵。它有很多用法，访问 git stash 页面了解更多。&lt;/p&gt;</description></item><item><title>Git检查仓库状态</title><link>http://www.gitfaq.cn/docs/git-recipes/Git-checks-the-status-of-the-repository/</link><pubDate>Tue, 11 Mar 2025 10:10:12 +0800</pubDate><guid>http://www.gitfaq.cn/docs/git-recipes/Git-checks-the-status-of-the-repository/</guid><description>&lt;h1 id="git检查仓库状态"&gt;Git检查仓库状态&lt;a class="anchor" href="#git%e6%a3%80%e6%9f%a5%e4%bb%93%e5%ba%93%e7%8a%b6%e6%80%81" aria-label="Link"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;blockquote class=''&gt;&#10;&lt;p&gt;BY 童仲毅（&lt;a href="https://gitfaq.cn/docs/git-recipes/"&gt;geeeeeeeeek@github&lt;/a&gt;）&lt;/p&gt;&#10;&lt;p&gt;这是一篇在&lt;a href="https://www.atlassian.com/git/tutorials/inspecting-a-repository/git-log"&gt;原文（BY atlassian）&lt;/a&gt;基础上演绎的译文。除非另行注明，页面上所有内容采用知识共享-署名（&lt;a href="http://creativecommons.org/licenses/by/2.5/au/deed.zh"&gt;CC BY 2.5 AU&lt;/a&gt;）协议共享。&lt;/p&gt;&#10;&lt;/blockquote&gt;&lt;h2 id="git-status"&gt;git status&lt;a class="anchor" href="#git-status" aria-label="Link"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;git status&lt;/code&gt; 命令显示工作目录和缓存区的状态。你可以看到哪些更改被缓存了，哪些还没有，以及哪些还未被 Git 追踪。status 的输出 &lt;em&gt;不会&lt;/em&gt; 告诉你任何已提交到项目历史的信息。如果你想看的话，应该使用 &lt;code&gt;git log&lt;/code&gt; 命令。&lt;/p&gt;&#10;&lt;h3 id="git-status用法"&gt;&lt;code&gt;git status&lt;/code&gt;用法&lt;a class="anchor" href="#git-status%e7%94%a8%e6%b3%95" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git status&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;列出已缓存、未缓存、未追踪的文件。&lt;/p&gt;&#10;&lt;h3 id="讨论"&gt;讨论&lt;a class="anchor" href="#%e8%ae%a8%e8%ae%ba" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;p&gt;&lt;code&gt;git status&lt;/code&gt; 是一个相对简单的命令。 它告诉你 &lt;code&gt;git add&lt;/code&gt; 和 &lt;code&gt;git commit&lt;/code&gt; 的进展。status 信息还包括了添加缓存和移除缓存的相关指令。样例输出显示了三类主要的 &lt;code&gt;git status&lt;/code&gt; 输出：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#78787e"&gt;# On branch master&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#78787e"&gt;# Changes to be committed:&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#78787e"&gt;# (use &amp;#34;git reset HEAD &amp;lt;file&amp;gt;...&amp;#34; to unstage)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#78787e"&gt;#&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#78787e"&gt;#modified: hello.py&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#78787e"&gt;#&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#78787e"&gt;# Changes not staged for commit:&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#78787e"&gt;# (use &amp;#34;git add &amp;lt;file&amp;gt;...&amp;#34; to update what will be committed)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#78787e"&gt;# (use &amp;#34;git checkout -- &amp;lt;file&amp;gt;...&amp;#34; to discard changes in working directory)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#78787e"&gt;#&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#78787e"&gt;#modified: main.py&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#78787e"&gt;#&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#78787e"&gt;# Untracked files:&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#78787e"&gt;# (use &amp;#34;git add &amp;lt;file&amp;gt;...&amp;#34; to include in what will be committed)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#78787e"&gt;#&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#78787e"&gt;#hello.pyc&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="忽略文件"&gt;忽略文件&lt;a class="anchor" href="#%e5%bf%bd%e7%95%a5%e6%96%87%e4%bb%b6" aria-label="Link"&gt;&lt;/a&gt;&lt;/h4&gt;&#10;&lt;p&gt;未追踪的文件通常有两类。它们要么是项目新增但还未提交的文件，要么是像 &lt;code&gt;.pyc&lt;/code&gt;、&lt;code&gt;.obj&lt;/code&gt;、&lt;code&gt;.exe&lt;/code&gt; 等编译后的二进制文件。显然前者应该出现在 &lt;code&gt;git status&lt;/code&gt; 的输出中，而后者会让我们困惑究竟发生了什么。&lt;/p&gt;</description></item><item><title>Git检出之前的提交</title><link>http://www.gitfaq.cn/docs/git-recipes/Git-checks-out-the-previous-commit/</link><pubDate>Sun, 24 Nov 2024 16:50:12 +0800</pubDate><guid>http://www.gitfaq.cn/docs/git-recipes/Git-checks-out-the-previous-commit/</guid><description>&lt;h1 id="git检出之前的提交"&gt;Git检出之前的提交&lt;a class="anchor" href="#git%e6%a3%80%e5%87%ba%e4%b9%8b%e5%89%8d%e7%9a%84%e6%8f%90%e4%ba%a4" aria-label="Link"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;blockquote class=''&gt;&#10;&lt;p&gt;BY 童仲毅（&lt;a href="https://gitfaq.cn/docs/git-recipes/"&gt;geeeeeeeeek@github&lt;/a&gt;）&lt;/p&gt;&#10;&lt;p&gt;这是一篇在&lt;a href="https://www.atlassian.com/git/tutorials/viewing-old-commits"&gt;原文（BY atlassian）&lt;/a&gt;基础上演绎的译文。除非另行注明，页面上所有内容采用知识共享-署名（&lt;a href="http://creativecommons.org/licenses/by/2.5/au/deed.zh"&gt;CC BY 2.5 AU&lt;/a&gt;）协议共享。&lt;/p&gt;&#10;&lt;/blockquote&gt;&lt;h2 id="git-checkout"&gt;git checkout&lt;a class="anchor" href="#git-checkout" aria-label="Link"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;git checkout&lt;/code&gt; 这个命令有三个不同的作用：检出文件、检出提交和检出分支。在这一章中，我们只关心前两种用法。&lt;/p&gt;&#10;&lt;p&gt;检出提交会使工作目录和这个提交完全匹配。你可以用它来查看项目之前的状态，而不改变当前的状态。检出文件使你能够查看某个特定文件的旧版本，而工作目录中剩下的文件不变。&lt;/p&gt;&#10;&lt;h3 id="git-checkout用法"&gt;&lt;code&gt;git checkout&lt;/code&gt;用法&lt;a class="anchor" href="#git-checkout%e7%94%a8%e6%b3%95" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git checkout master&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;回到 master 分支。分支会在下一节中讲到，而现在，你只需要将它视为回到项目「当前」状态的一种方式。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git checkout &amp;lt;commit&amp;gt; &amp;lt;file&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;查看文件之前的版本。它将工作目录中的 &lt;code&gt;&amp;lt;file&amp;gt;&lt;/code&gt; 文件变成 &lt;code&gt;&amp;lt;commit&amp;gt;&lt;/code&gt; 中那个文件的拷贝，并将它加入缓存区。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git checkout &amp;lt;commit&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;更新工作目录中的所有文件，使得和某个特定提交中的文件一致。你可以将提交的哈希字串，或是标签作为 &lt;code&gt;&amp;lt;commit&amp;gt;&lt;/code&gt; 参数。这会使你处在分离 HEAD 的状态。&lt;/p&gt;&#10;&lt;h3 id="讨论"&gt;讨论&lt;a class="anchor" href="#%e8%ae%a8%e8%ae%ba" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;p&gt;版本控制系统背后的思想就是「安全」地储存项目的拷贝，这样你永远不用担心什么时候不可复原地破坏了你的代码库。当你建立了项目历史之后，&lt;code&gt;git checkout&lt;/code&gt; 是一种便捷的方式，来将保存的快照「加载」到你的开发机器上去。&lt;/p&gt;&#10;&lt;p&gt;检出之前的提交是一个只读操作。在查看旧版本的时候绝不会损坏你的仓库。你项目「当前」的状态在&#9;&lt;code&gt;master&lt;/code&gt; 上不会变化。在开发的正常阶段，&lt;code&gt;HEAD&lt;/code&gt; 一般指向 master 或是其他的本地分支，但当你检出之前提交的时候，&lt;code&gt;HEAD&lt;/code&gt; 就不再指向一个分支了——它直接指向一个提交。这被称为「分离 &lt;code&gt;HEAD&lt;/code&gt;」状态 ，可以用下图可视化：&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="https://www.atlassian.com/git/images/tutorials/getting-started/viewing-old-commits/01.svg" alt="Git Tutorial: Checking out a previous commit" /&gt;&lt;/p&gt;&#10;&lt;p&gt;在另一方面，检出旧文件不影响你仓库的当前状态。你可以在新的快照中像其他文件一样重新提交旧版本。所以，在效果上，&lt;code&gt;git checkout&lt;/code&gt; 的这个用法可以用来将单个文件回滚到旧版本 。&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="https://www.atlassian.com/git/images/tutorials/getting-started/viewing-old-commits/02.svg" alt="Git Training: Checking out a previous version of a file" /&gt;&lt;/p&gt;</description></item><item><title>Git回滚错误的修改</title><link>http://www.gitfaq.cn/docs/git-recipes/Git-rollsback-the-wrong-modifications/</link><pubDate>Sun, 24 Nov 2024 16:50:12 +0800</pubDate><guid>http://www.gitfaq.cn/docs/git-recipes/Git-rollsback-the-wrong-modifications/</guid><description>&lt;h1 id="git回滚错误的修改"&gt;Git回滚错误的修改&lt;a class="anchor" href="#git%e5%9b%9e%e6%bb%9a%e9%94%99%e8%af%af%e7%9a%84%e4%bf%ae%e6%94%b9" aria-label="Link"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;blockquote class=''&gt;&#10;&lt;p&gt;BY 童仲毅（&lt;a href="https://gitfaq.cn/docs/git-recipes/"&gt;geeeeeeeeek@github&lt;/a&gt;）&lt;/p&gt;&#10;&lt;p&gt;这是一篇在&lt;a href="https://www.atlassian.com/git/tutorials/undoing-changes"&gt;原文（BY atlassian）&lt;/a&gt;基础上演绎的译文。除非另行注明，页面上所有内容采用知识共享-署名（&lt;a href="http://creativecommons.org/licenses/by/2.5/au/deed.zh"&gt;CC BY 2.5 AU&lt;/a&gt;）协议共享。&lt;/p&gt;&#10;&lt;/blockquote&gt;&lt;p&gt;这章教程提供了和项目旧版本打交道所需要的所有技巧。首先，你会知道如何浏览旧的提交，然后了解回滚项目历史中的公有提交和回滚本地机器上的私有更改之间的区别。&lt;/p&gt;&#10;&lt;h2 id="git-checkout"&gt;git checkout&lt;a class="anchor" href="#git-checkout" aria-label="Link"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;见上一章&lt;a href="http://www.gitfaq.cn/docs/git-recipes/Git-checks-out-the-previous-commit/#git-checkout#git-checkout"&gt;「2.5 检出之前的提交」&lt;/a&gt;。&lt;/p&gt;&#10;&lt;h2 id="git-revert"&gt;git revert&lt;a class="anchor" href="#git-revert" aria-label="Link"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;git revert&lt;/code&gt; 命令用来撤销一个已经提交的快照。但是，它是通过搞清楚如何撤销这个提交引入的更改，然后在最后加上一个撤销了更改的 &lt;em&gt;新&lt;/em&gt; 提交，而不是从项目历史中移除这个提交。这避免了Git丢失项目历史，这一点对于你的版本历史和协作的可靠性来说是很重要的。&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="http://www.gitfaq.cn/imgs/454f9ca5b0320.svg" alt="Git Tutorial: git revert" /&gt;&lt;/p&gt;&#10;&lt;h3 id="git-revert用法"&gt;&lt;code&gt;git revert&lt;/code&gt;用法&lt;a class="anchor" href="#git-revert%e7%94%a8%e6%b3%95" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git revert &amp;lt;commit&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;生成一个撤消了 &lt;code&gt;&amp;lt;commit&amp;gt;&lt;/code&gt; 引入的修改的新提交，然后应用到当前分支。&lt;/p&gt;&#10;&lt;h3 id="讨论"&gt;讨论&lt;a class="anchor" href="#%e8%ae%a8%e8%ae%ba" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;p&gt;撤销（revert）应该用在你想要在项目历史中移除一整个提交的时候。比如说，你在追踪一个 bug，然后你发现它是由一个提交造成的，这时候撤销就很有用。与其说自己去修复它，然后提交一个新的快照，不如用 &lt;code&gt;git revert&lt;/code&gt;，它帮你做了所有的事情。&lt;/p&gt;&#10;&lt;h4 id="撤销revert和重设reset对比"&gt;撤销（revert）和重设（reset）对比&lt;a class="anchor" href="#%e6%92%a4%e9%94%80revert%e5%92%8c%e9%87%8d%e8%ae%bereset%e5%af%b9%e6%af%94" aria-label="Link"&gt;&lt;/a&gt;&lt;/h4&gt;&#10;&lt;p&gt;理解这一点很重要。&lt;code&gt;git revert&lt;/code&gt; 回滚了「单独一个提交」，它没有移除后面的提交，然后回到项目之前的状态。在 Git 中，后者实际上被称为 &lt;code&gt;reset&lt;/code&gt;，而不是 &lt;code&gt;revert&lt;/code&gt;。&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="http://www.gitfaq.cn/imgs/9e48dec8fd2f.svg" alt="Git Tutorial: Revert vs Reset" /&gt;&lt;/p&gt;&#10;&lt;p&gt;撤销和重设相比有两个重要的优点。首先，它不会改变项目历史，对那些已经发布到共享仓库的提交来说这是一个安全的操作。至于为什么改变共享的历史是危险的，请参阅 &lt;code&gt;git reset&lt;/code&gt; 一节。&lt;/p&gt;&#10;&lt;p&gt;其次，&lt;code&gt;git revert&lt;/code&gt; 可以针对历史中任何一个提交，而 &lt;code&gt;git reset&lt;/code&gt; 只能从当前提交向前回溯。比如，你想用 &lt;code&gt;git reset&lt;/code&gt; 重设一个旧的提交，你不得不移除那个提交后的所有提交，再移除那个提交，然后重新提交后面的所有提交。不用说，这并不是一个优雅的回滚方案。&lt;/p&gt;</description></item><item><title>Git创建Pull Request</title><link>http://www.gitfaq.cn/docs/git-recipes/Git-creates-a-pull-request/</link><pubDate>Tue, 11 Mar 2025 08:50:12 +0800</pubDate><guid>http://www.gitfaq.cn/docs/git-recipes/Git-creates-a-pull-request/</guid><description>&lt;h1 id="git创建pullrequest"&gt;Git创建Pull Request&lt;a class="anchor" href="#git%e5%88%9b%e5%bb%bapullrequest" aria-label="Link"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;blockquote class=''&gt;&#10;&lt;p&gt;BY 童仲毅（&lt;a href="https://gitfaq.cn/docs/git-recipes/"&gt;geeeeeeeeek@github&lt;/a&gt;）&lt;/p&gt;&#10;&lt;p&gt;这是一篇在&lt;a href="https://www.atlassian.com/git/tutorials/making-a-pull-request"&gt;原文（BY atlassian）&lt;/a&gt;基础上演绎的译文。除非另行注明，页面上所有内容采用知识共享-署名（&lt;a href="http://creativecommons.org/licenses/by/2.5/au/deed.zh"&gt;CC BY 2.5 AU&lt;/a&gt;）协议共享。&lt;/p&gt;&#10;&lt;p&gt;原文以 Bitbucket 为例，考虑到&lt;a href="https://gitfaq.cn/docs/git-recipes/"&gt;git-recipes&lt;/a&gt;主要面向 GitHub 用户，因此例子替换成了 GitHub。Pull Request 在 GitLab 等平台上也有，用法和本教程基本一致。&lt;/p&gt;&#10;&lt;/blockquote&gt;&lt;p&gt;Pull Request 是开发者使用 GitHub 进行协作的利器。这个功能为用户提供了友好的页面，让提议的更改在并入官方项目之前，可以得到充分的讨论。&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="http://www.gitfaq.cn/imgs/8ece897e-c516-11e5-91c0-f7a44434478f.png" alt="qq20160127-0" /&gt;&lt;/p&gt;&#10;&lt;p&gt;最简单地来说，Pull Request 是一种机制，让开发者告诉项目成员一个功能已经完成。一旦 feature 分支开发完毕，开发者使用 GitHub 账号提交一个 Pull Request。它告诉所有参与者，他们需要审查代码，并将代码并入 &lt;code&gt;master&lt;/code&gt; 分支。&lt;/p&gt;&#10;&lt;p&gt;但是，Pull Request 不只是一个通知，还是一个专注于某个提议功能的讨论版。 如果更改导致了任何问题，团队成员可以在 Pull Request 下发布反馈，甚至推送后续提交来修改这个 Pull Request。所有的活动都在这个 Pull Request里之间追踪。&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="http://www.gitfaq.cn/imgs/3a787656c6102.svg" alt="Git Workflows: Activity inside a Pull Request" /&gt;&lt;/p&gt;&#10;&lt;p&gt;和其他协作模型相比，这种共享提交的解决方案形成了更加线性的工作流。SVN 和 Git 都能通过一个简单的脚本发送通知邮件；但是，如果要讨论更改，开发者不得不在邮件里回复。这会变得愈发杂乱无章，尤其是后续提交出现时。Pull Request 将所有这些功能放入了一个友好的网页，在每个 GitHub 仓库上方都能找到。&lt;/p&gt;&#10;&lt;h3 id="剖析一个-pull-request"&gt;剖析一个 Pull Request&lt;a class="anchor" href="#%e5%89%96%e6%9e%90%e4%b8%80%e4%b8%aa-pull-request" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;p&gt;当你提交一个 Pull Request 的时候，你做的事情是 &lt;em&gt;请求（request）&lt;/em&gt; 另一个开发者（比如项目维护者）来 &lt;em&gt;拉取（pull）&lt;/em&gt; 你仓库中的一个分支到他们的仓库。也就是说你需要提供 4 个信息来完成一个 Pull Request：源仓库、源分支、目标仓库、目标分支。&lt;/p&gt;</description></item><item><title>Git使用分支</title><link>http://www.gitfaq.cn/docs/git-recipes/Git-uses-branches/</link><pubDate>Tue, 11 Mar 2025 11:40:12 +0800</pubDate><guid>http://www.gitfaq.cn/docs/git-recipes/Git-uses-branches/</guid><description>&lt;h1 id="git使用分支"&gt;Git使用分支&lt;a class="anchor" href="#git%e4%bd%bf%e7%94%a8%e5%88%86%e6%94%af" aria-label="Link"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;blockquote class=''&gt;&#10;&lt;p&gt;BY 童仲毅（&lt;a href="https://gitfaq.cn/docs/git-recipes/"&gt;geeeeeeeeek@github&lt;/a&gt;）&lt;/p&gt;&#10;&lt;p&gt;这是一篇在&lt;a href="https://www.atlassian.com/git/tutorials/using-branches"&gt;原文（BY atlassian）&lt;/a&gt;基础上演绎的译文。除非另行注明，页面上所有内容采用知识共享-署名（&lt;a href="http://creativecommons.org/licenses/by/2.5/au/deed.zh"&gt;CC BY 2.5 AU&lt;/a&gt;）协议共享。&lt;/p&gt;&#10;&lt;/blockquote&gt;&lt;p&gt;这份教程是 Git 分支的综合介绍。首先，我们简单讲解如何创建分支，就像请求一份新的项目历史一样。然后，我们会看到 git checkout 是如何切换分支的。最后，学习一下 git merge 是如何整合独立分支的历史。&lt;/p&gt;&#10;&lt;p&gt;我们已经知道，Git 分支和 SVN 分支不同。SVN 分支只被用来记录偶尔大规模的开发效果，而 Git 分支是你日常工作流中不可缺失的一部分。&lt;/p&gt;&#10;&lt;h2 id="git-branch"&gt;git branch&lt;a class="anchor" href="#git-branch" aria-label="Link"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;分支代表了一条独立的开发流水线。分支是我们在第二篇中讨论过的「编辑/缓存/提交」流程的抽象。你可以把它看作请求全新「工作目录、缓存区、项目历史」的一种方式。新的提交被存放在当前分支的历史中，导致了项目历史被 fork 了一份。&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;git branch&lt;/code&gt; 命令允许你创建、列出、重命名和删除分支。它不允许你切换分支或是将被 fork 的历史放回去。因此，&lt;code&gt;git branch&lt;/code&gt; 和 &lt;code&gt;git checkout&lt;/code&gt;、&lt;code&gt;git merge&lt;/code&gt; 这两个命令通常紧密地结合在一起使用。&lt;/p&gt;&#10;&lt;h3 id="git-branch用法"&gt;&lt;code&gt;git branch&lt;/code&gt;用法&lt;a class="anchor" href="#git-branch%e7%94%a8%e6%b3%95" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git branch&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;列出仓库中所有分支。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git branch &amp;lt;branch&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;创建一个名为 &lt;code&gt;&amp;lt;branch&amp;gt;&lt;/code&gt; 的分支。&lt;em&gt;不会&lt;/em&gt; 自动切换到那个分支去。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git branch -d &amp;lt;branch&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;删除指定分支。这是一个安全的操作，Git 会阻止你删除包含未合并更改的分支。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git branch -D &amp;lt;branch&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;强制删除指定分支，即使包含未合并更改。如果你希望永远删除某条开发线的所有提交，你应该用这个命令。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git branch -m &amp;lt;branch&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;将当前分支命名为 &lt;code&gt;&amp;lt;branch&amp;gt;&lt;/code&gt;。&lt;/p&gt;&#10;&lt;h3 id="讨论"&gt;讨论&lt;a class="anchor" href="#%e8%ae%a8%e8%ae%ba" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;p&gt;在 Git 中，分支是你日常开发流程中的一部分。当你想要添加一个新的功能或是修复一个 bug 时——不管 bug 是大是小——你都应该新建一个分支来封装你的修改。这确保了不稳定的代码永远不会被提交到主代码库中，它同时给了你机会，在并入主分支前清理你 feature 分支的历史。&lt;/p&gt;</description></item><item><title>Git常见工作流比较</title><link>http://www.gitfaq.cn/docs/git-recipes/Comparison-of-common-Git-workflows/</link><pubDate>Tue, 11 Mar 2025 14:41:12 +0800</pubDate><guid>http://www.gitfaq.cn/docs/git-recipes/Comparison-of-common-Git-workflows/</guid><description>&lt;h1 id="git常见工作流比较"&gt;Git常见工作流比较&lt;a class="anchor" href="#git%e5%b8%b8%e8%a7%81%e5%b7%a5%e4%bd%9c%e6%b5%81%e6%af%94%e8%be%83" aria-label="Link"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;blockquote class=''&gt;&#10;&lt;p&gt;BY 童仲毅（&lt;a href="https://gitfaq.cn/docs/git-recipes/"&gt;geeeeeeeeek@github&lt;/a&gt;）&lt;/p&gt;&#10;&lt;p&gt;这是一篇在&lt;a href="https://www.atlassian.com/git/tutorials/comparing-workflows"&gt;原文（BY atlassian）&lt;/a&gt;基础上演绎的译文。除非另行注明，页面上所有内容采用知识共享-署名（&lt;a href="http://creativecommons.org/licenses/by/2.5/au/deed.zh"&gt;CC BY 2.5 AU&lt;/a&gt;）协议共享。&lt;/p&gt;&#10;&lt;/blockquote&gt;&lt;p&gt;多种多样的工作流使得在项目中实施 Git 时变得难以选择。这份教程提供了一个出发点，调查企业团队最常见的 Git 工作流。&lt;/p&gt;&#10;&lt;p&gt;阅读的时候，请记住工作流应该是一种规范而不是金科玉律。我们希望向你展示所有工作流，让你融会贯通，因地制宜。&lt;/p&gt;&#10;&lt;p&gt;这份教程讨论了下面四种工作流：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="http://www.gitfaq.cn/docs/git-recipes/Comparison-of-common-Git-workflows/#%E4%B8%AD%E5%BF%83%E5%8C%96%E7%9A%84%E5%B7%A5%E4%BD%9C%E6%B5%81#%e4%b8%ad%e5%bf%83%e5%8c%96%e7%9a%84%e5%b7%a5%e4%bd%9c%e6%b5%81"&gt;中心化的工作流&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="http://www.gitfaq.cn/docs/git-recipes/Comparison-of-common-Git-workflows/#%E5%8A%9F%E8%83%BD%E5%88%86%E6%94%AF%E7%9A%84%E5%B7%A5%E4%BD%9C%E6%B5%81#%e5%8a%9f%e8%83%bd%e5%88%86%e6%94%af%e7%9a%84%e5%b7%a5%e4%bd%9c%e6%b5%81"&gt;基于功能分支的工作流&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="http://www.gitfaq.cn/docs/git-recipes/Comparison-of-common-Git-workflows/#gitflow%E5%B7%A5%E4%BD%9C%E6%B5%81#gitflow%e5%b7%a5%e4%bd%9c%e6%b5%81"&gt;Gitflow工作流&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="http://www.gitfaq.cn/docs/git-recipes/Comparison-of-common-Git-workflows/#fork%E5%B7%A5%E4%BD%9C%E6%B5%81#fork%e5%b7%a5%e4%bd%9c%e6%b5%81"&gt;Fork工作流&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="中心化的工作流"&gt;中心化的工作流&lt;a class="anchor" href="#%e4%b8%ad%e5%bf%83%e5%8c%96%e7%9a%84%e5%b7%a5%e4%bd%9c%e6%b5%81" aria-label="Link"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;&lt;img src="http://www.gitfaq.cn/imgs/Workflow.svg" alt="Git Workflows: SVN-style Workflow" /&gt;&lt;/p&gt;&#10;&lt;p&gt;过渡到分布式分版本控制系统看起来是个令人恐惧的任务，但你不必为了利用 Git 的优点而改变你现有的工作流。你的团队仍然可以用以前SVN的方式开发项目。&lt;/p&gt;&#10;&lt;p&gt;然而，使用 Git 来驱动你的开发工作流显示出了一些SVN没有的优点。首先，它让每个开发者都有了自己 &lt;em&gt;本地&lt;/em&gt; 的完整项目副本。隔离的环境使得每个开发者的工作独立于项目的其它修改——他们可以在自己的本地仓库中添加提交，完全无视上游的开发，直到需要的时候。&lt;/p&gt;&#10;&lt;p&gt;第二，它让你接触到了 Git 鲁棒的分支和合并模型。和 SVN 不同，Git 分支被设计为一种故障安全的机制，用来在仓库之间整合代码和共享更改。&lt;/p&gt;&#10;&lt;h2 id="如何工作"&gt;如何工作&lt;a class="anchor" href="#%e5%a6%82%e4%bd%95%e5%b7%a5%e4%bd%9c" aria-label="Link"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;和 Subversion 一样，中心化的工作流将中央仓库作为项目中所有修改的唯一入口。和 &lt;code&gt;trunk&lt;/code&gt; 不同，默认的开发分支叫做&lt;code&gt;master&lt;/code&gt;，所有更改都被提交到这个分支。这种工作流不需要 &lt;code&gt;master&lt;/code&gt; 之外的其它分支。&lt;/p&gt;&#10;&lt;p&gt;开发者将中央仓库克隆到本地后开始工作。在他们的本地项目副本中，他们可以像SVN一样修改文件和提交更改；不过，这些新的提交被保存在 &lt;em&gt;本地&lt;/em&gt; ——它们和中央仓库完全隔离。这使得开发者可以将和上游的同步推迟到他们方便的时候。&lt;/p&gt;&#10;&lt;p&gt;为了向官方项目发布修改，开发者将他们的本地 &lt;code&gt;master&lt;/code&gt; 分支「推送」到中央仓库。这一步等同于 &lt;code&gt;svn commit&lt;/code&gt;，除了Git添加的是所有不在中央 &lt;code&gt;master&lt;/code&gt; 分支上的本地提交。&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="http://www.gitfaq.cn/imgs/33340383ce0702.svg" alt="Central and local repositories" /&gt;&lt;/p&gt;&#10;&lt;h3 id="管理冲突"&gt;管理冲突&lt;a class="anchor" href="#%e7%ae%a1%e7%90%86%e5%86%b2%e7%aa%81" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;p&gt;中央仓库代表官方项目，因此它的提交历史应该被视作神圣不可更改的。如果开发者的本地提交和中央仓库分叉了，Git 会拒绝将他们的修改推送上去，因为这会覆盖官方提交。&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="http://www.gitfaq.cn/imgs/a2e93374e53e0320.svg" alt="Managing Conflicts" /&gt;&lt;/p&gt;</description></item><item><title>Git图解</title><link>http://www.gitfaq.cn/docs/git-recipes/Git-diagram/</link><pubDate>Sun, 24 Nov 2024 16:50:12 +0800</pubDate><guid>http://www.gitfaq.cn/docs/git-recipes/Git-diagram/</guid><description>&lt;h1 id="git图解"&gt;Git图解&lt;a class="anchor" href="#git%e5%9b%be%e8%a7%a3" aria-label="Link"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;blockquote class=''&gt;&#10;&lt;p&gt;BY 童仲毅（&lt;a href="https://gitfaq.cn/docs/git-recipes/"&gt;geeeeeeeeek@github&lt;/a&gt;）&lt;/p&gt;&#10;&lt;p&gt;这是一篇在&lt;a href="http://marklodato.github.io/visual-git-guide/index-zh-cn.html"&gt;原文&lt;/a&gt;基础上演绎的文章。原作者 &lt;a href="lodatom@gmail.com"&gt;Mark Lodato&lt;/a&gt;，译者 &lt;a href="ellrywych@gmail.com"&gt;wych&lt;/a&gt;。原文采用&lt;a href="https://creativecommons.org/licenses/by-nc-sa/3.0/us/"&gt;创用 CC 姓名标示-非商业性-相同方式分享 3.0 美国授权条款&lt;/a&gt;授权。&lt;/p&gt;&#10;&lt;/blockquote&gt;&lt;p&gt;此页图解 git 中的最常用命令。如果你稍微理解 git 的工作原理，这篇文章能够让你理解的更透彻。&lt;/p&gt;&#10;&lt;h2 id="基本用法"&gt;基本用法&lt;a class="anchor" href="#%e5%9f%ba%e6%9c%ac%e7%94%a8%e6%b3%95" aria-label="Link"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;&lt;img src="http://www.gitfaq.cn/imgs/git-basic-usage.svg" alt="enter image description here" /&gt;&lt;/p&gt;&#10;&lt;p&gt;上面的四条命令在工作目录、stage 缓存(也叫做索引)和 commit 历史之间复制文件。&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;git add files&lt;/code&gt; 把工作目录中的文件加入 stage 缓存&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;git commit&lt;/code&gt; 把 stage 缓存生成一次 commit，并加入 commit 历史&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;git reset -- files&lt;/code&gt; 撤销最后一次 &lt;code&gt;git add files&lt;/code&gt;，你也可以用 &lt;code&gt;git reset&lt;/code&gt; 撤销所有 stage 缓存文件&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;git checkout -- files&lt;/code&gt; 把文件从 stage 缓存复制到工作目录，用来丢弃本地修改&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;你可以用 &lt;code&gt;git reset -p&lt;/code&gt;、&lt;code&gt;git checkout -p&lt;/code&gt; 或 &lt;code&gt;git add -p&lt;/code&gt; 进入交互模式，也可以跳过 stage 缓存直接从 commit历史取出文件或者直接提交代码。&lt;/p&gt;</description></item><item><title>Git代码合并选Merge还是Rebase</title><link>http://www.gitfaq.cn/docs/git-recipes/Merge-Git-code-Merge-or-Rebase/</link><pubDate>Sun, 24 Nov 2024 16:50:12 +0800</pubDate><guid>http://www.gitfaq.cn/docs/git-recipes/Merge-Git-code-Merge-or-Rebase/</guid><description>&lt;h1 id="git代码合并选merge还是rebase"&gt;Git代码合并选Merge还是Rebase&lt;a class="anchor" href="#git%e4%bb%a3%e7%a0%81%e5%90%88%e5%b9%b6%e9%80%89merge%e8%bf%98%e6%98%afrebase" aria-label="Link"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;blockquote class=''&gt;&#10;&lt;p&gt;BY 童仲毅（&lt;a href="https://gitfaq.cn/docs/git-recipes/"&gt;geeeeeeeeek@github&lt;/a&gt;）&lt;/p&gt;&#10;&lt;p&gt;这是一篇在&lt;a href="https://www.atlassian.com/git/tutorials/merging-vs-rebasing"&gt;原文（BY atlassian）&lt;/a&gt;基础上演绎的译文。除非另行注明，页面上所有内容采用知识共享-署名（&lt;a href="http://creativecommons.org/licenses/by/2.5/au/deed.zh"&gt;CC BY 2.5 AU&lt;/a&gt;）协议共享。&lt;/p&gt;&#10;&lt;/blockquote&gt;&lt;p&gt;&lt;code&gt;git rebase&lt;/code&gt; 这个命令经常被人认为是一种 Git 巫术，初学者应该避而远之。但如果使用得当的话，它能给你的团队开发省去太多烦恼。在这篇文章中，我们会比较 &lt;code&gt;git rebase&lt;/code&gt; 和类似的 &lt;code&gt;git merge&lt;/code&gt; 命令，找到 Git 工作流中 rebase 的所有用法。&lt;/p&gt;&#10;&lt;h2 id="概述"&gt;概述&lt;a class="anchor" href="#%e6%a6%82%e8%bf%b0" aria-label="Link"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;你要知道的第一件事是，&lt;code&gt;git rebase&lt;/code&gt; 和&lt;code&gt;git merge&lt;/code&gt; 做的事其实是一样的。它们都被设计来将一个分支的更改并入另一个分支，只不过方式有些不同。&lt;/p&gt;&#10;&lt;p&gt;想象一下，你刚创建了一个专门的分支开发新功能，然后团队中另一个成员在 master 分支上添加了新的提交。这就会造成提交历史被 fork 一份，用 Git 来协作的开发者应该都很清楚。&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="http://www.gitfaq.cn/imgs/c4d86bc7cb0b.svg" alt="enter image description here" /&gt;&lt;/p&gt;&#10;&lt;p&gt;现在，如果 master 中新的提交和你的工作是相关的。为了将新的提交并入你的分支，你有两个选择：merge 或 rebase。&lt;/p&gt;&#10;&lt;h3 id="merge"&gt;Merge&lt;a class="anchor" href="#merge" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;p&gt;将 master 分支合并到 feature 分支最简单的办法就是用下面这些命令：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git checkout feature&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git merge master&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;或者，你也可以把它们压缩在一行里。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git merge master feature&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;feature 分支中新的合并提交（merge commit）将两个分支的历史连在了一起。你会得到下面这样的分支结构：&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="http://www.gitfaq.cn/imgs/e1e1baa9405502.svg" alt="enter image description here" /&gt;&lt;/p&gt;</description></item><item><title>Git代码回滚选Reset、Checkout还是Revert</title><link>http://www.gitfaq.cn/docs/git-recipes/Git-code-rollback-Reset-Checkout-or-Revert/</link><pubDate>Sun, 24 Nov 2024 16:50:12 +0800</pubDate><guid>http://www.gitfaq.cn/docs/git-recipes/Git-code-rollback-Reset-Checkout-or-Revert/</guid><description>&lt;h1 id="git代码回滚选resetcheckout还是revert"&gt;Git代码回滚选Reset、Checkout还是Revert&lt;a class="anchor" href="#git%e4%bb%a3%e7%a0%81%e5%9b%9e%e6%bb%9a%e9%80%89resetcheckout%e8%bf%98%e6%98%afrevert" aria-label="Link"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;blockquote class=''&gt;&#10;&lt;p&gt;BY 童仲毅（&lt;a href="https://gitfaq.cn/docs/git-recipes/"&gt;geeeeeeeeek@github&lt;/a&gt;）&lt;/p&gt;&#10;&lt;p&gt;这是一篇在&lt;a href="https://www.atlassian.com/git/tutorials/resetting-checking-out-and-reverting"&gt;原文（BY atlassian）&lt;/a&gt;基础上演绎的译文。除非另行注明，页面上所有内容采用知识共享-署名（&lt;a href="http://creativecommons.org/licenses/by/2.5/au/deed.zh"&gt;CC BY 2.5 AU&lt;/a&gt;）协议共享。&lt;/p&gt;&#10;&lt;/blockquote&gt;&lt;p&gt;&lt;code&gt;git reset&lt;/code&gt;、&lt;code&gt;git checkout&lt;/code&gt; 和 &lt;code&gt;git revert&lt;/code&gt; 是你的 Git 工具箱中最有用的一些命令。它们都用来撤销代码仓库中的某些更改，而前两个命令不仅可以作用于提交，还可以作用于特定文件。&lt;/p&gt;&#10;&lt;p&gt;因为它们非常相似，所以我们经常会搞混，不知道什么场景下该用哪个命令。在这篇文章中，我们会比较 &lt;code&gt;git reset&lt;/code&gt;、&lt;code&gt;git checkout&lt;/code&gt; 和 &lt;code&gt;git revert&lt;/code&gt; 最常见的用法。希望你在看完后能游刃有余地使用这些命令来管理你的仓库。&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="http://www.gitfaq.cn/imgs/faf2aec53cc3.svg" alt="Git repo的主要组成" /&gt;&lt;/p&gt;&#10;&lt;p&gt;Git 仓库有三个主要组成——工作目录，缓存区和提交历史。这张图有助于理解每个命令到底产生了哪些影响。当你阅读的时候，牢记这张图。&lt;/p&gt;&#10;&lt;h2 id="提交层面的操作"&gt;提交层面的操作&lt;a class="anchor" href="#%e6%8f%90%e4%ba%a4%e5%b1%82%e9%9d%a2%e7%9a%84%e6%93%8d%e4%bd%9c" aria-label="Link"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;你传给 &lt;code&gt;git reset&lt;/code&gt; 和 &lt;code&gt;git checkout&lt;/code&gt; 的参数决定了它们的作用域。如果你没有包含文件路径，这些操作对所有提交生效。我们这一节要探讨的就是提交层面的操作。注意，&lt;code&gt;git revert&lt;/code&gt; 没有文件层面的操作。&lt;/p&gt;&#10;&lt;h3 id="reset"&gt;Reset&lt;a class="anchor" href="#reset" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;p&gt;在提交层面上，reset 将一个分支的末端指向另一个提交。这可以用来移除当前分支的一些提交。比如，下面这两条命令让 hotfix 分支向后回退了两个提交。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git checkout hotfix&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git reset HEAD~2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;hotfix 分支末端的两个提交现在变成了悬挂提交。也就是说，下次 Git 执行垃圾回收的时候，这两个提交会被删除。换句话说，如果你想扔掉这两个提交，你可以这么做。reset 操作如下图所示：&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="http://www.gitfaq.cn/imgs/02-updated.png" alt="把hotfix分支reset到HEAD~2" /&gt;&lt;/p&gt;&#10;&lt;p&gt;如果你的更改还没有共享给别人，&lt;code&gt;git reset&lt;/code&gt; 是撤销这些更改的简单方法。当你开发一个功能的时候发现「糟糕，我做了什么？我应该重新来过！」时，reset 就像是 go-to 命令一样。&lt;/p&gt;&#10;&lt;p&gt;除了在当前分支上操作，你还可以通过传入这些标记来修改你的缓存区或工作目录：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&amp;ndash;soft – 缓存区和工作目录都不会被改变&lt;/li&gt;&#10;&lt;li&gt;&amp;ndash;mixed – 默认选项。缓存区和你指定的提交同步，但工作目录不受影响&lt;/li&gt;&#10;&lt;li&gt;&amp;ndash;hard – 缓存区和工作目录都同步到你指定的提交&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;把这些标记想成定义 &lt;code&gt;git reset&lt;/code&gt; 操作的作用域就容易理解多了。&lt;/p&gt;</description></item><item><title>Git log高级用法</title><link>http://www.gitfaq.cn/docs/git-recipes/Advanced-usage-of-Git-log/</link><pubDate>Sun, 24 Nov 2024 16:50:12 +0800</pubDate><guid>http://www.gitfaq.cn/docs/git-recipes/Advanced-usage-of-Git-log/</guid><description>&lt;h1 id="git-log高级用法"&gt;Git log高级用法&lt;a class="anchor" href="#git-log%e9%ab%98%e7%ba%a7%e7%94%a8%e6%b3%95" aria-label="Link"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;blockquote class=''&gt;&#10;&lt;p&gt;BY 童仲毅（&lt;a href="https://gitfaq.cn/docs/git-recipes/"&gt;geeeeeeeeek@github&lt;/a&gt;）&lt;/p&gt;&#10;&lt;p&gt;这是一篇在&lt;a href="https://www.atlassian.com/git/tutorials/git-log"&gt;原文（BY atlassian）&lt;/a&gt;基础上演绎的译文。除非另行注明，页面上所有内容采用知识共享-署名（&lt;a href="http://creativecommons.org/licenses/by/2.5/au/deed.zh"&gt;CC BY 2.5 AU&lt;/a&gt;）协议共享。&lt;/p&gt;&#10;&lt;/blockquote&gt;&lt;p&gt;每一个版本控制系统的出现都是为了让你记录代码的变化。你可以看到项目的历史记录——谁贡献了什么、bug 是什么时候引入的，还可以撤回有问题的更改。但是，首先你得知道如何使用它。这也就是为什么会有 &lt;code&gt;git log&lt;/code&gt; 这个命令。&lt;/p&gt;&#10;&lt;p&gt;到现在为止，你应该已经知道如何用 &lt;code&gt;git log&lt;/code&gt; 命令来显示最基本的提交信息。但除此之外，你还可以传入各种不同的参数来获得不一样的输出。&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;git log&lt;/code&gt; 有两个高级用法：一是自定义提交的输出格式，二是过滤输出哪些提交。这两个用法合二为一，你就可以找到你项目中你需要的任何信息。&lt;/p&gt;&#10;&lt;h2 id="格式化-log-输出"&gt;格式化 Log 输出&lt;a class="anchor" href="#%e6%a0%bc%e5%bc%8f%e5%8c%96-log-%e8%be%93%e5%87%ba" aria-label="Link"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;首先，这篇文章会展示几种 &lt;code&gt;git log&lt;/code&gt; 格式化输出的例子。大多数例子只是通过标记向 &lt;code&gt;git log&lt;/code&gt; 请求或多或少的信息。&lt;/p&gt;&#10;&lt;p&gt;如果你不喜欢默认的 &lt;code&gt;git log&lt;/code&gt; 格式，你可以用 &lt;code&gt;git config&lt;/code&gt; 的别名功能来给你想要的格式创建一个快捷方式。&lt;/p&gt;&#10;&lt;h3 id="oneline"&gt;Oneline&lt;a class="anchor" href="#oneline" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;p&gt;&lt;code&gt;--oneline&lt;/code&gt; 标记把每一个提交压缩到了一行中。它默认只显示提交ID和提交信息的第一行。&lt;code&gt;git log --oneline&lt;/code&gt; 的输出一般是这样的：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;0e25143 Merge branch &lt;span style="color:#5af78e"&gt;&amp;#39;feature&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ad8621a Fix a bug in the feature&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;16b36c6 Add a new feature&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;23ad9ad Add the initial code base&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;它对于获得项目的总体情况很有帮助。&lt;/p&gt;&#10;&lt;h3 id="decorate"&gt;Decorate&lt;a class="anchor" href="#decorate" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;p&gt;很多时候，知道每个提交关联的分支或者标签很有用。&lt;code&gt;--decorate&lt;/code&gt; 标记让 &lt;code&gt;git log&lt;/code&gt; 显示指向这个提交的所有引用（比如说分支、标签等）。&lt;/p&gt;</description></item><item><title>Git 钩子：自定义你的工作流</title><link>http://www.gitfaq.cn/docs/git-recipes/Git-hooks-Customize-your-workflow/</link><pubDate>Sun, 24 Nov 2024 16:50:12 +0800</pubDate><guid>http://www.gitfaq.cn/docs/git-recipes/Git-hooks-Customize-your-workflow/</guid><description>&lt;h1 id="git-钩子自定义你的工作流"&gt;Git 钩子：自定义你的工作流&lt;a class="anchor" href="#git-%e9%92%a9%e5%ad%90%e8%87%aa%e5%ae%9a%e4%b9%89%e4%bd%a0%e7%9a%84%e5%b7%a5%e4%bd%9c%e6%b5%81" aria-label="Link"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;blockquote class=''&gt;&#10;&lt;p&gt;BY 童仲毅（&lt;a href="https://gitfaq.cn/docs/git-recipes/"&gt;geeeeeeeeek@github&lt;/a&gt;）&lt;/p&gt;&#10;&lt;p&gt;这是一篇在&lt;a href="https://www.atlassian.com/git/tutorials/git-hooks"&gt;原文（BY atlassian）&lt;/a&gt;基础上演绎的译文。除非另行注明，页面上所有内容采用知识共享-署名（&lt;a href="http://creativecommons.org/licenses/by/2.5/au/deed.zh"&gt;CC BY 2.5 AU&lt;/a&gt;）协议共享。&lt;/p&gt;&#10;&lt;/blockquote&gt;&lt;p&gt;Git 钩子是在 Git 仓库中特定事件发生时自动运行的脚本。它可以让你自定义 Git 内部的行为，在开发周期中的关键点触发自定义的行为。&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="http://www.gitfaq.cn/imgs/git-hook.svg" alt="git hook" /&gt;&lt;/p&gt;&#10;&lt;p&gt;Git 钩子最常见的使用场景包括推行提交规范，根据仓库状态改变项目环境，和接入持续集成工作流。但是，因为脚本可以完全定制，你可以用 Git 钩子来自动化或者优化你开发工作流中任意部分。&lt;/p&gt;&#10;&lt;p&gt;在这篇文章中，我们会先简要介绍 Git 钩子是如何工作的。然后，我们会审视一些本地和远端仓库使用最流行的钩子。&lt;/p&gt;&#10;&lt;h2 id="git钩子概述"&gt;Git钩子概述&lt;a class="anchor" href="#git%e9%92%a9%e5%ad%90%e6%a6%82%e8%bf%b0" aria-label="Link"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;Git 钩子是仓库中特定事件发生时 Git 自动运行的普通脚本。因此，Git 钩子安装和配置也非常容易。&lt;/p&gt;&#10;&lt;p&gt;钩子在本地或服务端仓库都可以部署，且只会在仓库中事件发生时被执行。在文章后面我们会具体地研究各种钩子。接下来所讲的配置对本地和服务端钩子都起作用。&lt;/p&gt;&#10;&lt;h3 id="安装钩子"&gt;安装钩子&lt;a class="anchor" href="#%e5%ae%89%e8%a3%85%e9%92%a9%e5%ad%90" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;p&gt;钩子存在于每个 Git 仓库的 &lt;code&gt;.git/hooks&lt;/code&gt; 目录中。当你初始化仓库时，Git 自动生成这个目录和一些示例脚本。当你观察 &lt;code&gt;.git/hooks&lt;/code&gt; 时，你会看到下面这些文件：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;applypatch-msg.sample pre-push.sample&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;commit-msg.sample pre-rebase.sample&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;post-update.sample prepare-commit-msg.sample&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pre-applypatch.sample update.sample&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pre-commit.sample&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里已经包含了大部分可用的钩子了，但是 &lt;code&gt;.sample&lt;/code&gt; 拓展名防止它们默认被执行。为了安装一个钩子，你只需要去掉 &lt;code&gt;.sample&lt;/code&gt; 拓展名。或者你要写一个新的脚本，你只需添加一个文件名和上述匹配的新文件，去掉 &lt;code&gt;.sample&lt;/code&gt; 拓展名。&lt;/p&gt;&#10;&lt;p&gt;比如说，试试安装一个 &lt;code&gt;prepare-commit-msg&lt;/code&gt; 钩子。去掉脚本的 &lt;code&gt;.sample&lt;/code&gt; 拓展名，在文件中加上下面这两行：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#78787e"&gt;#!/bin/sh&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff5c57"&gt;echo&lt;/span&gt; &lt;span style="color:#5af78e"&gt;&amp;#34;# Please include a useful commit message!&amp;#34;&lt;/span&gt; &amp;gt; &lt;span style="color:#ff5c57"&gt;$1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;钩子需要能被执行，所以如果你创建了一个新的脚本文件，你需要修改它的文件权限。比如说，为了确保 &lt;code&gt;prepare-commit-msg&lt;/code&gt; 可执行，运行下面这个命令：&lt;/p&gt;</description></item><item><title>Git提交引用和引用日志</title><link>http://www.gitfaq.cn/docs/git-recipes/Git-commit-references-and-reference-logs/</link><pubDate>Sun, 24 Nov 2024 16:50:12 +0800</pubDate><guid>http://www.gitfaq.cn/docs/git-recipes/Git-commit-references-and-reference-logs/</guid><description>&lt;h1 id="git提交引用和引用日志"&gt;Git提交引用和引用日志&lt;a class="anchor" href="#git%e6%8f%90%e4%ba%a4%e5%bc%95%e7%94%a8%e5%92%8c%e5%bc%95%e7%94%a8%e6%97%a5%e5%bf%97" aria-label="Link"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;blockquote class=''&gt;&#10;&lt;p&gt;BY 童仲毅（&lt;a href="https://gitfaq.cn/docs/git-recipes/"&gt;geeeeeeeeek@github&lt;/a&gt;）&lt;/p&gt;&#10;&lt;p&gt;这是一篇在&lt;a href="https://www.atlassian.com/git/tutorials/refs-and-the-reflog"&gt;原文（BY atlassian）&lt;/a&gt;基础上演绎的译文。除非另行注明，页面上所有内容采用知识共享-署名（&lt;a href="http://creativecommons.org/licenses/by/2.5/au/deed.zh"&gt;CC BY 2.5 AU&lt;/a&gt;）协议共享。&lt;/p&gt;&#10;&lt;/blockquote&gt;&lt;p&gt;提交是 Git 的精髓所在，你无时不刻不在创建和缓存提交、查看以前的提交，或者用各种Git命令在仓库间转移你的提交。大多数的命令都对同一个提交操作，而有些会接受提交的引用作为参数。比如，你可以给 &lt;code&gt;git checkout&lt;/code&gt; 传入一个引用来查看以前的提交，或者传入一个分支名来切换到对应的分支。&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="http://www.gitfaq.cn/imgs/git-to-commit.svg" alt="引用一次提交的各种方式" /&gt;&lt;/p&gt;&#10;&lt;p&gt;知道提交的各种引用方式之后，Git 的命令就会变得更加强大。在这章中，我们研究提交的各种引用方式，来一窥 &lt;code&gt;git checkout&lt;/code&gt;、&lt;code&gt;git branch&lt;/code&gt;、&lt;code&gt;git push&lt;/code&gt; 等命令的工作原理。&lt;/p&gt;&#10;&lt;p&gt;我们还会学到如何使用 Git 的引用日志查看似乎已被删除的提交。&lt;/p&gt;&#10;&lt;h2 id="哈希字串"&gt;哈希字串&lt;a class="anchor" href="#%e5%93%88%e5%b8%8c%e5%ad%97%e4%b8%b2" aria-label="Link"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;引用一个提交最直接的方式是通过 SHA-1 的哈希字串，这是每个提交唯一的 ID。你可以在 &lt;code&gt;git log&lt;/code&gt; 的输出中找到提交的哈希字串。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;commit 0c708fdec272bc4446c6cabea4f0022c2b616eba&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Author: Mary Johnson &amp;lt;mary@example.com&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Date: Wed Jul &lt;span style="color:#ff9f43"&gt;9&lt;/span&gt; 16:37:42 &lt;span style="color:#ff9f43"&gt;2014&lt;/span&gt; -0500&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 一些提交信息&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在 Git 命令中传递时，你只需要提供足以确定那个提交的哈希子串即可。比如，你可以这样用 &lt;code&gt;git show&lt;/code&gt; 的命令显示上面的提交：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git show 0c708f&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;有时，我们需要把分支、标签或者其他间接的引用转变成对应提交的哈希。&lt;code&gt;git rev-parse&lt;/code&gt; 命令正是你需要的。下面这个命令返回 master 分支提交的哈希字串：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git rev-parse master&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;当你写的自定义脚本中需要将提交引用作为参数时，这个命令非常有用。你可以让 &lt;code&gt;git rev-parse&lt;/code&gt; 帮你处理转换，而不用手动做这件事。&lt;/p&gt;&#10;&lt;h2 id="引用"&gt;引用&lt;a class="anchor" href="#%e5%bc%95%e7%94%a8" aria-label="Link"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;ref 是提交的间接引用。你可以把它当做哈希字串的别名，但对用户更友好。这就是 Git 内部表示分支和标签的机制。&lt;/p&gt;</description></item><item><title>Git重写项目历史</title><link>http://www.gitfaq.cn/docs/git-recipes/Git-rewrites-project-history/</link><pubDate>Tue, 11 Mar 2025 10:31:12 +0800</pubDate><guid>http://www.gitfaq.cn/docs/git-recipes/Git-rewrites-project-history/</guid><description>&lt;h1 id="git重写项目历史"&gt;Git重写项目历史&lt;a class="anchor" href="#git%e9%87%8d%e5%86%99%e9%a1%b9%e7%9b%ae%e5%8e%86%e5%8f%b2" aria-label="Link"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;blockquote class=''&gt;&#10;&lt;p&gt;BY 童仲毅（&lt;a href="https://gitfaq.cn/docs/git-recipes/"&gt;geeeeeeeeek@github&lt;/a&gt;）&lt;/p&gt;&#10;&lt;p&gt;这是一篇在&lt;a href="https://www.atlassian.com/git/tutorials/rewriting-history"&gt;原文（BY atlassian）&lt;/a&gt;基础上演绎的译文。除非另行注明，页面上所有内容采用知识共享-署名（&lt;a href="http://creativecommons.org/licenses/by/2.5/au/deed.zh"&gt;CC BY 2.5 AU&lt;/a&gt;）协议共享。&lt;/p&gt;&#10;&lt;/blockquote&gt;&lt;h2 id="概述"&gt;概述&lt;a class="anchor" href="#%e6%a6%82%e8%bf%b0" aria-label="Link"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;Git 的主要职责是保证你不会丢失提交的修改。但是，它同样被设计成让你完全掌控开发工作流。这包括了让你自定义你的项目历史，而这也创造了丢失提交的可能性。Git 提供了可以重写项目历史的命令，但也警告你这些命令可能会让你丢失内容。&lt;/p&gt;&#10;&lt;p&gt;这份教程讨论了重写提交快照的一些常见原因，并告诉你如何避免不好的影响。&lt;/p&gt;&#10;&lt;h2 id="git-commit-amend"&gt;git commit &amp;ndash;amend&lt;a class="anchor" href="#git-commit-amend" aria-label="Link"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;git commit --amend&lt;/code&gt; 命令是修复最新提交的便捷方式。它允许你将缓存的修改和之前的提交合并到一起，而不是提交一个全新的快照。它还可以用来简单地编辑上一次提交的信息而不改变快照。&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="http://www.gitfaq.cn/imgs/cea9ad4f205f01.svg" alt="Git Tutorial: git commit &amp;ndash;amend" /&gt;&lt;/p&gt;&#10;&lt;p&gt;但是，amend 不只是修改了最新的提交——它进行了一次替换。对于 Git 来说，这看上去像一个全新的提交，即上图中用星号表示的那一个。在公共仓库工作时一定要牢记这一点。&lt;/p&gt;&#10;&lt;h3 id="git-commit---amend用法"&gt;&lt;code&gt;git commit --amend&lt;/code&gt;用法&lt;a class="anchor" href="#git-commit---amend%e7%94%a8%e6%b3%95" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git commit --amend&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;合并缓存的修改和上一次的提交，用新的快照替换上一个提交。缓存区没有文件时运行这个命令可以用来编辑上次提交的提交信息，而不会更改快照。&lt;/p&gt;&#10;&lt;h3 id="讨论"&gt;讨论&lt;a class="anchor" href="#%e8%ae%a8%e8%ae%ba" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;p&gt;仓促的提交在你日常开发过程中时常会发生。很容易就忘记了缓存一个文件或者弄错了提交信息的格式。&lt;code&gt;--amend&lt;/code&gt; 标记是修复这些小意外的便捷方式。&lt;/p&gt;&#10;&lt;h4 id="不要修复公共提交"&gt;不要修复公共提交&lt;a class="anchor" href="#%e4%b8%8d%e8%a6%81%e4%bf%ae%e5%a4%8d%e5%85%ac%e5%85%b1%e6%8f%90%e4%ba%a4" aria-label="Link"&gt;&lt;/a&gt;&lt;/h4&gt;&#10;&lt;p&gt;在&lt;a href="http://www.gitfaq.cn/docs/git-recipes/Git-rollsback-the-wrong-modifications/#git-reset#git-reset"&gt;&lt;code&gt;git reset&lt;/code&gt;&lt;/a&gt;这节中，我们说过永远不要重设和其他开发者共享的提交。对于修复也是一样：永远不要修复一个已经推送到公共仓库中的提交。&lt;/p&gt;&#10;&lt;p&gt;修复过的提交事实上是全新的提交，之前的提交会被移除出项目历史。这和重设公共快照的后果是一样的。如果你修复了其他开发者在之后继续开发的一个提交，看上去他们的工作基础从项目历史中消失了一样。对于在这上面的开发者来说这是很困惑的，而且很难恢复。&lt;/p&gt;&#10;&lt;h3 id="例子"&gt;例子&lt;a class="anchor" href="#%e4%be%8b%e5%ad%90" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;p&gt;下面这个🌰展示了 Git 开发工作流中的一个常见情形。我们编辑了一些希望在同一个快照中提交的文件，但我们忘记添加了其中的一个。修复错误只需要缓存那个文件并且用 &lt;code&gt;--amend&lt;/code&gt; 标记提交：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#78787e"&gt;# 编辑 hello.py 和 main.py&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git add hello.py&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git commit&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#78787e"&gt;# 意识到你忘记添加 main.py 的更改&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git add main.py&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git commit --amend --no-edit&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;编辑器会弹出上一次提交的信息，加入 &lt;code&gt;--no-edit&lt;/code&gt; 标记会修复提交但不修改提交信息。需要的话你可以修改，不然的话就像往常一样保存并关闭文件。完整的提交会替换之前不完整的提交，看上去就像我们在同一个快照中提交了 &lt;code&gt;hello.py&lt;/code&gt; 和 &lt;code&gt;main.py&lt;/code&gt;。&lt;/p&gt;</description></item><item><title>Git保持同步</title><link>http://www.gitfaq.cn/docs/git-recipes/Git-stays-in-sync/</link><pubDate>Tue, 11 Mar 2025 09:50:12 +0800</pubDate><guid>http://www.gitfaq.cn/docs/git-recipes/Git-stays-in-sync/</guid><description>&lt;h1 id="git保持同步"&gt;Git保持同步&lt;a class="anchor" href="#git%e4%bf%9d%e6%8c%81%e5%90%8c%e6%ad%a5" aria-label="Link"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;blockquote class=''&gt;&#10;&lt;p&gt;BY 童仲毅（&lt;a href="https://gitfaq.cn/docs/git-recipes/"&gt;geeeeeeeeek@github&lt;/a&gt;）&lt;/p&gt;&#10;&lt;p&gt;这是一篇在&lt;a href="https://www.atlassian.com/git/tutorials/syncing"&gt;原文（BY atlassian）&lt;/a&gt;基础上演绎的译文。除非另行注明，页面上所有内容采用知识共享-署名（&lt;a href="http://creativecommons.org/licenses/by/2.5/au/deed.zh"&gt;CC BY 2.5 AU&lt;/a&gt;）协议共享。&lt;/p&gt;&#10;&lt;/blockquote&gt;&lt;p&gt;SVN 使用唯一的中央仓库作为开发者之间沟通的桥梁，在开发者的工作拷贝和中央仓库之间传递变更集合（changeset），协作得以发生。这和Git的协作模型有所不同，Git 给予每个开发者一份自己的仓库拷贝，拥有自己完整的本地历史和分支结构。用户通常共享一系列的提交而不是单个变更集合。Git 允许你在仓库间共享整个分支，而不是从工作副本提交一个差异集合到中央仓库。&lt;/p&gt;&#10;&lt;p&gt;下面的命令让你管理仓库之间的连接，将分支「推送」到其他仓库来发布本地历史，或是将分支「拉取」到本地仓库来查看其它开发者的贡献。&lt;/p&gt;&#10;&lt;h2 id="git-remote"&gt;git remote&lt;a class="anchor" href="#git-remote" aria-label="Link"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;git remote&lt;/code&gt; 命令允许你创建、查看和删除和其它仓库之间的连接。远程连接更像是书签，而不是直接跳转到其他仓库的链接。它用方便记住的别名引用不那么方便记住的 URL，而不是提供其他仓库的实时连接。&lt;/p&gt;&#10;&lt;p&gt;例如，下图显示了你的仓库和中央仓库以及另一个开发者仓库之间的远程连接。你可以向 Git 命令传递 origin 和 john 的别名来引用这些仓库，替代完整的 URL。&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="http://www.gitfaq.cn/imgs/1d3fcd6603801.svg" alt="Git Tutorial: git remote" /&gt;&lt;/p&gt;&#10;&lt;h3 id="git-remote用法"&gt;&lt;code&gt;git remote&lt;/code&gt;用法&lt;a class="anchor" href="#git-remote%e7%94%a8%e6%b3%95" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git remote&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;列出你和其他仓库之间的远程连接。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git remote -v&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;和上个命令相同，但同时显示每个连接的 URL。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git remote add &amp;lt;name&amp;gt; &amp;lt;url&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;创建一个新的远程仓库连接。在添加之后，你可以将 &lt;code&gt;&amp;lt;name&amp;gt;&lt;/code&gt; 作为 &lt;code&gt;&amp;lt;url&amp;gt;&lt;/code&gt; 便捷的别名在其他 Git 命令中使用。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git remote rm &amp;lt;name&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;移除名为&lt;name&gt;的远程仓库的连接。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git remote rename &amp;lt;old-name&amp;gt; &amp;lt;new-name&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;将远程连接从 &lt;code&gt;&amp;lt;old-name&amp;gt;&lt;/code&gt; 重命名为 &lt;code&gt;&amp;lt;new-name&amp;gt;&lt;/code&gt;。&lt;/p&gt;&#10;&lt;h3 id="讨论"&gt;讨论&lt;a class="anchor" href="#%e8%ae%a8%e8%ae%ba" aria-label="Link"&gt;&lt;/a&gt;&lt;/h3&gt;&#10;&lt;p&gt;Git 被设计为给每个开发者提供完全隔离的开发环境。也就是说信息并不是自动地在仓库之间传递。开发者需要手动将上游提交拉取到本地，或手动将本地提交推送到中央仓库中去。&lt;code&gt;git remote&lt;/code&gt; 命令正是将 URL 传递给这些「共享」命令的快捷方式。&lt;/p&gt;</description></item></channel></rss>