Git 入门：术语基础
Git

> 
> 想学习 Git？看看这个最重要的术语和命令的快速总结。
> 
> 
> 


![](/data/attachment/album/202101/08/171156gu9l8dvulxmxom6d.jpg "Digital hand surrounding by objects, bike, light bulb, graphs")


如今，对于任何希望跟踪他们的变化的人来说，版本控制是一个重要的工具。它对程序员、系统管理员和<ruby> 网站可靠性工程师 <rt>  site reliability engineers </rt></ruby>（SRE）都特别有用。确保可以从错误中恢复到已知的良好状态是一个巨大的胜利，比以前给复制的文件添加 `.old` 后缀的策略更友好。


但学习 Git 这件事往往被告诉大家“投身开源”的好心同行们过度简化了。在你还不明白之前，就有人要你给一个从<ruby> 上游 <rt>  upstream </rt></ruby> <ruby> 变基 <rt>  rebase </rt></ruby>的<ruby> 拉取请求 <rt>  pull request </rt></ruby>（PR）或<ruby> 合并请求 <rt>  merge request </rt></ruby>（MR），然后他们才能从你的<ruby> 远程版本库 <rt>  remote </rt></ruby>合并 —— 而且一定会删除<ruby> 合并提交 <rt>  merge commits </rt></ruby>。无论你想给开源项目做出什么好的贡献，当你看到这些你不认识的单词时，都会觉得难以融入。


![Git 速查表封面图](/data/attachment/album/202101/08/171207av0lvu3z688ubg8l.jpg "Git Cheat Sheet cover image")


* [下载](https://opensource.com/downloads/cheat-sheet-git) 我们的 Git 速查表。


如果你有一两个月的时间和足够的好奇心，[Git SCM](https://git-scm.com/about) 是你需要学习所有术语的权威来源。但如果你正在寻找来自实践的总结，请继续阅读。


### 提交就是提醒


对我来说，Git 最难理解的部分是 Git 最简单的概念：一个<ruby> 提交 <rt>  commit </rt></ruby>就是一个内容的集合，包括一个关于描述的信息，以及之前的提交。没有固有的代码发布策略，甚至没有内置的明确建议。这个内容甚至不一定是代码 —— 可以是*任何*你想添加到版本库的东西。<ruby> 提交消息 <rt>  commit message </rt></ruby>会对这些内容进行注释。


我喜欢把提交信息看作是给未来的自己的礼物：它可能会提到你编辑的文件，但更重要的是它提醒你修改这些文件的意图。添加更多关于你为什么编辑这些内容的信息，可以帮助任何使用你的版本库的人，即使那个人是你。


### origin/master 在哪里？


要知道自己在 Git 项目中的位置，首先把它想成一棵树。所有 Git 项目都有一个根目录，类似于文件系统的根目录。所有的提交都是这个根目录下的分支。这样一来，分支只是一个提交的指针。按照惯例，`master` 是根目录下默认的分支名称。（LCTT 译注：世界变得快，原文发表于 2019 年，而现在有些地方开始用 `main` 替代这个名字。）


由于 Git 是一个分布式的版本控制系统，同一个代码库分布在多个地方，所以人们经常用<ruby> 版本库 <rt>  repository </rt></ruby>这个词来表示同一个项目的所有副本。（LCTT 译注：“repository” 英文原意是仓库、存储库，在计算机环境中，常用于版本控制、软件分发等方面，有时候会统一译作“仓库”、“存储库”。但我们认为，应该根据不同语境采用更有指向性的译法。在 Git 等版本控制语境中，采用“版本库”；在软件分发方面，采用“软件库”；其它泛指或不确定的语境中，可采用“仓库”、“存储库”译法。）有<ruby> 本地版本库 <rt>  local repository </rt></ruby>，这是你编辑代码的地方（稍后会有更多的介绍），还有<ruby> 远程版本库 <rt>  remote repository </rt></ruby>，这是你完成后想把代码发送到的地方。远程版本库可以在任何地方，甚至在你的本地版本库所在的同一台计算机上，但它们通常托管在 GitLab 或 GitHub 等版本库服务上。


### 我在哪里？


虽然不是官方的卖点，但迷路也是 Git 仓库的“乐趣”之一。你可以通过这套可靠的命令来找到自己的方向：


* `git branch` —— 找到你所在的分支。
* `git log` —— 查看你正在进行的提交。
* `git status` —— 查看自上次提交以来你所做的编辑。
* `git remote` —— 查看你正在跟踪的远程仓库。


用这些命令来定位自己的方向，当你被卡住的时候，会让你有一种方向感。


### 我是否已将我的提交暂存或缓存起来？


你电脑上的代码俗称为你的<ruby> 工作空间 <rt>  workspace </rt></ruby>。但不是很明显的是，当你在 Git 仓库中时，你还有两个（是的，两个！）其他位置：<ruby> 索引 <rt>  index </rt></ruby>和<ruby> 暂存 <rt>  stash </rt></ruby>。当你写了一些内容，然后**添加**时，你是把它添加到索引中，也就是准备提交的缓存内容。有的时候，你的索引中的文件还没有准备好提交，但你想查看另一个分支。这时，暂存就派上用场了。你可以使用 `git stash` 将索引了但尚未提交的文件存储到暂存区中。当你准备好取回文件时，运行 `git stash pop` 将更改带回索引中。


下面是一些你需要使用暂存区和缓存区的命令：


* `git diff ...origin/master` —— 显示最近的本地提交和远程的 `origin` 版本库的 `master` 分支之间的差异。
* `git diff --cached` —— 显示最近的本地提交与添加到本地索引的内容之间的任何差异。
* `git stash` —— 将索引的（已添加但未提交的）文件放在暂存区堆栈中。
* `git stash list` —— 显示暂存区堆栈中的变化。
* `git stash pop` —— 将最近的变化从暂存库中删除。


### 无头骑士


Git 里面有各种比喻。当我想到 `HEAD` 是哪里的时候，我就会想到火车线路。如果你最终处于<ruby> 脱离的 HEAD <rt>  detached HEAD </rt></ruby>模式，就意味着你已经脱离了这个隐喻的轨道。


`HEAD` 是指向当前签出分支中最近一次提交的指针。默认的“签出checkout”是指当你创建一个 Git 仓库并进入到 `master` 分支的时候。每次创建或修改到另一个分支时，你都会切换到该分支行。如果你在当前分支的某处进行 `git checkout <commit>`，`HEAD` 就会移动到该提交。如果没有提交历史记录将你的当前提交连接到已签出的提交，那么你将处于脱离的 `HEAD` 状态。如果你找不到 `HEAD` 的位置，你可以随时用 `git reset --hard origin/master` 来删除修改，回到已知状态。*警告：这将删除你上次推送到 `master` 后的任何改动。*


### 你是上游还是下游？


你的项目的本地副本被认为是你的本地版本库，它可能有也可能没有远程版本库 —— 远程版本库的副本是用于协作或保存的。也可能还有一个<ruby> 上游 <rt>  upstream </rt></ruby>版本库，在那里，项目的第三个副本由不同的贡献者托管和维护。


例如，假设我想为 Kubernetes 做贡献。我会首先将 `kubernetes/kubernetes` 项目<ruby> 复刻 <rt>  fork </rt></ruby>到我的账户下 `mbbroberg/kubernetes`。然后我会将我的项目克隆到我的本地工作区。在这种情况下，我的本地克隆是我的本地仓库，`mbbroberg/kubernetes` 是我的远程仓库，`kubernetes/kubernetes` 是上游。


### 合并的隐喻


当你深入 Git 分支时，根系统的视觉效果就会和火车轨道的形象合二为一。分支通常被用作开发一个新功能的方式，最终你想把它<ruby> 合并 <rt>  merge </rt></ruby>到主分支中。当这样做时，Git 会按顺序保留共同的提交历史，然后将你的分支的新提交追加到历史中。这个过程有一大堆的细节：是否<ruby> 变基 <rt>  rebase </rt></ruby>，是否添加一个<ruby> 合并提交 <rt>  merge commit </rt></ruby>，[Brent Laster](https://opensource.com/users/bclaster) 在《[如何在 Git 中重置、恢复和返回之前的状态](https://opensource.com/article/18/6/git-reset-revert-rebase-commands)》中会有更详细的探讨。


### 我想现在就去 Git


要掌握 Git 命令的世界，有大量的术语和需要探索的地方。我希望这篇关于日常使用术语的第一人称探索能帮助你适应这一切。如果你觉得自己被卡住了或者遇到了挫折，欢迎在 Twitter [@mbbroberg](https://twitter.com/mbbroberg) 上联系我。


#### 回顾


* <ruby> 提交 <rt>  Commit </rt></ruby> —— 将当前索引的内容保存在一个新的提交中，并附上用户描述更改的日志信息。
* <ruby> 分支 <rt>  Branch </rt></ruby> —— 指向一个提交的指针。
* `master` —— 第一个分支的默认名称。
* `HEAD` —— 指向当前分支上最近一次提交的指针。
* <ruby> 合并 <rt>  Merge </rt></ruby> —— 合并两个或多个提交的历史。
* <ruby> 工作空间 <rt>  Workspace </rt></ruby> —— Git 仓库本地副本的通俗名称。
* <ruby> 工作树 <rt>  Working tree </rt></ruby> —— 工作区中的当前分支；任何时候你都可以在 `git status` 的输出中看到这个。
* <ruby> 缓存 <rt>  Cache </rt></ruby> —— 用于临时存储未提交的变更的空间。
* <ruby> 索引 <rt>  Index </rt></ruby> —— 变更提交前存储其变化的缓存。
* 跟踪和未跟踪的文件 —— 没有被索引缓存的文件或尚未加入其中的文件。
* <ruby> 暂存 <rt>  Stash </rt></ruby> —— 另一个缓存，作为一个堆栈，在这里可以存储更改而不需要提交它们。
* `origin` —— 远程版本库的默认名称。
* <ruby> 本地仓库 <rt>  Local repository </rt></ruby> —— 也就是你在工作站上保存 Git 仓库副本的地方。
* <ruby> 远程存储库 <rt>  Remote repository </rt></ruby> —— Git 存储库的第二副本，你可以在这里推送变更以便协作或备份。
* <ruby> 上游存储库 <rt>  Upstream repository </rt></ruby> —— 你跟踪的远程存储库的通俗说法。
* <ruby> 拉取请求 <rt>  Pull request </rt></ruby> —— 这是 GitHub 的专用术语，用于让其他人知道你推送到仓库分支的变化。
* <ruby> 合并请求 <rt>  Merge request </rt></ruby> —— 这是 GitLab 的专用术语，用于让其他人知道你推送到仓库分支的变化。
* `origin/master` —— 远程版本库及其主要分支的默认名称。


后记：双关语是 Git 最好的部分之一，愿你喜欢。




---


via: <https://opensource.com/article/19/2/git-terminology>


作者：[Matthew Broberg](https://opensource.com/users/mbbroberg) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


OK
Version control is an important tool for anyone looking to track their changes these days. It's especially helpful for programmers, sysadmins, and site reliability engineers (SREs) alike. The promise of recovering from mistakes to a known good state is a huge win and a touch friendlier than the previous strategy of adding ** .old** to a copied file.

But learning Git is often oversimplified by well-meaning peers telling everyone to "get into open source." Before you know it, someone asks for a *pull request* or *merge request *where you *rebase* from *upstream* before they can merge from your *remote*—and be sure to remove *merge commits*. Whatever well-working contribution you want to give back to an open source project feels much further from being added when you look at all these words you don't know.

If you have a month or two and enough curiosity, [Git SCM](https://git-scm.com/about) is the definitive source for all the terms you need to learn. If you're looking for a summary from the trenches, keep reading.

## Reminder: What's a commit?

The toughest part of Git for me to internalize was the simplest idea of Git: *a commit is a collection of content, a message about how you got there, and the commits that came before it*. There's no inherent code release strategy or even strong opinions built in. The content doesn't even have to be code—it is *anything* you want to add to the repository. The commit message annotates that content.

I like to think of a commit message as a gift to your future self: it may mention the files you edited, but more importantly it reminds you of your intention for changing those files. Adding more about why you have edited what you have helps anyone who uses your repository, even when that person is you.

## There's no place like 'origin/main'

Knowing where you are in a Git project starts with thinking of a tree. All Git projects have a root, similar to the idea of a filesystem's root directory. All commits branch off from that root. In this way, a branch is only a pointer to a commit. By convention, **main** or **master **is the default name for the default branch in your root directory.

Since Git is a distributed version control system, where the same codebase is distributed to multiple locations, people often use the term "repository" as a way of talking about all copies of the same project. There is the *local repository*, where you edit your code (more on that in a minute), and the *remote repository*, the place where you want to send it after you're finished. Remotes can be anywhere, even on the same computer where your local repository is located, but they are often hosted on repository services like GitLab or GitHub.

## What's the pwd of Git commands?

While it's not an official selling point, being lost is part of the fun of a Git repository. You can find your way by running through this reliable set of commands:

-

—to find which branch you're on**git branch** -

—to see what commit you're on**git log** -

—to see what edits you've made since the last commit**git status** -

—to see what remote repository you're tracking**git remote**

Orienting yourself using these commands will give you a sense of direction when you're stuck.

## Have I stashed or cached my commit?

The code local to your computer is colloquially called your *workspace*. What is not immediately obvious is that you have two (yes, two!) other locations local to you when you are in a Git repository: *index* and *stash*. When you write some content and then **add** it, you are adding it to the index, which is the cached content that is ready to commit. There are times when you have files in the index that you are not ready to commit, but you want to view another branch. That's where the stash comes in handy. You can store indexed-but-not-yet-committed files to the stash using

. When you're ready to retrieve the file, run **git stash**

to bring changes back into the index.**git stash pop**

Here are some commands you'll need to use your stash and cache.

-

—to show the difference between the most recent local commit and the remote called "origin" and its branch called "master"**git diff ..origin/master** -

—to show any differences between the most recent local commit and what has been added to the local index**git diff --cached** -

—to place indexed (added but not committed) files in the stash stack**git stash** -

—to show what changes are in the stash stack**git stash list** -

—to take the most recent change off the stash stack**git stash pop**

## HEADless horseman

Git is a collection of all kinds of metaphors. When I think of where the HEAD is, I think of train lines. If you end up in a *detached HEAD* mode, it means you're off the metaphorical rails.

HEAD is a pointer to your most recent commit in the currently checked-out branch. The default "checkout" is when you create a Git repository and land on the **master** branch. Every time you create or change to another branch, you are on that branch line. If you

somewhere in your current branch, HEAD will move to that commit. If there is no commit history connecting your current commit to the commit you checked out, then you'll be in a detached HEAD state. If you ever lose your head finding where HEAD is, you can always **git checkout <commit>**

to delete changes and get back to a known state. **git reset --hard origin/master***Warning: this will delete any changes you have made since you last pushed to master.*

## Are you upstream or downstream?

The local copy of your project is considered your local repository. It may or may not have a remote repository—the place where you have a copy of your repository for collaboration or safekeeping. There may also be an *upstream* repository where a third copy of the project is hosted and maintained by a different set of contributors.

For instance, let's say I want to contribute to Kubernetes. I would first fork the **kubernetes/kubernetes** project to my account, **mbbroberg/kubernetes**. I would then clone my project to my local workspace. In this scenario, my local clone is my local repository, **mbbroberg/kubernetes** is my remote repository, and **kubernetes/kubernetes** is the upstream.

## Merging the metaphors

The visual of a root system merges with the train tracks image when you get deeper into Git branches. Branches are often used as ways of developing a new feature that you eventually want to *merge* into the master branch. When doing this, Git keeps the common history of commits in order then appends the new commits for your branch to the history. There are a ton of nuances to this process—whether to rebase or not, whether to add a merge commit or not—which [Brent Laster](https://opensource.com/users/bclaster) explores in greater detail in "[How to reset, revert, and return to previous states in Git](https://opensource.com/article/18/6/git-reset-revert-rebase-commands)."

## I think I Git it now

There is a ton of terminology and a lot to explore to master the world of Git commands. I hope this first-person exploration of how I use the terms day-to-day helps you acclimate to it all. If you ever feel stuck or frustrated, feel free to reach out to me on Twitter [@mbbroberg](https://twitter.com/mbbroberg).

### To review:

-
**Commit**—stores the current contents of the index in a new commit along with a log message from the user describing the changes -
**Branch**—a pointer to a commit -
**Master**—the default name for the first branch -
**HEAD**—a pointer to the most recent commit on the current branch -
**Merge**—joining two or more commit histories -
**Workspace**—the colloquial name for your local copy of a Git repository -
**Working tree**—the current branch in your workspace; you see this in

output all the time**git status** -
**Cache**—a space intended to temporarily store uncommitted changes -
**Index**—the cache where changes are stored before they are committed -
**Tracked and untracked files**—files either in the index cache or not yet added to it -
**Stash**—another cache, that acts as a stack, where changes can be stored without committing them -
**Origin**—the default name for a remote repository -
**Local repository**—another term for where you keep your copy of a Git repository on your workstation -
**Remote repository**—a secondary copy of a Git repository where you push changes for collaboration or backup -
**Upstream repository**—the colloquial term for a remote repository that you track -
**Pull request**—a GitHub-specific term to let others know about changes you've pushed to a branch in a repository -
**Merge request**—a GitLab-specific term to let others know about changes you've pushed to a branch in a repository -
**'origin/master'**—the default setting for a remote repository and its primary branch

Postscript: Puns are one of the best parts of Git. Have fun with them.

## 4 Comments