本教程提供的最重要的 Git 命令简明扼要地概述。首先,存储库中设置了本节介绍了所有您需要启动一个新的版本控制项目的工具。然后,剩余的部分介绍你日常的 Git 命令。
年底本模块,您应该能够创建一个 Git 仓库,保管,项目的记录快照并查看您的项目历史记录。
git init
的git init
命令将创建一个新的 Git 仓库。它可以用于将现有的非版本控制项目转换为一个 Git 仓库或初始化一个新的空的存储库。所以这通常是你会在一个新的项目中运行的第一个命令,在一个已初始化的存储库,没有可用的大多数其他 Git 命令。
执行git init
创建.git
在项目的根、 包含所有必需的元数据作为回购协议抵押品的子目录。除了从.git
目录中,现有的项目保持不变 (不像 SVN、 Git 不需要.git
在每个子目录中的文件夹)。
使用
git init
将当前目录转换为一个 Git 仓库。此操作将添加.git
到当前目录的文件夹,使它能够开始记录修订项目。
git init <directory>
在指定的目录中创建一个空的 Git 存储库。运行此命令将创建一个名为的新文件夹<directory
什么都不包含但.git
子目录。
git init --bare <directory>
初始化一个空的 Git 存储库,但省略的工作目录。共享存储库,则应始终会创建与--bare
标志 (见下文的讨论)。通常,存储库初始化的--bare
国旗而告终.git
.例如,一个存储库的裸机版本称为my-project
应存储在一个称为目录my-project.git
.
讨论
相比到 SVN,git init
命令是极其简单的方法来创建新的受版本控制的项目。Git 并不要求您创建一个存储库、 导入文件,并查阅工作副本。你要做的就是裁谈会进入你的项目文件夹和运行git init
你就会有一个功能齐全的 Git 仓库。
然而,对于大多数项目,git init
只需要执行一次,以创建一个中央存储库 — — 开发人员通常不使用 git init 创建他们本地的存储库。相反,他们通常会使用git clone
若要复制到他们的本地计算机上现有的存储库。
裸存储库
的--bare
标志创建一个存储库,没有一个工作目录,使它无法编辑文件并提交该存储库中的更改。总是应该作为裸存储库创建中央资料库,因为把树枝推到一个非裸存储库有可能覆盖所做更改。想想--bare
作为一种方式来标记一个存储库中的存储设备,反对开发环境。这意味着几乎所有的 Git 工作流,中央存储库是光秃秃的和开发人员本地资料库都非裸。
示例
自git clone
更方便的是,创建的项目中,最常见的使用情况,为本地副本git init
是创建一个中央存储库:
ssh <user>@<host>
cd path/above/repo
git init --bare my-project.git
第一,你到将包含您的中央存储库服务器的 SSH。然后,您导航到任何地方您想要存储该项目。最后,使用--bare
若要创建中央存储库的标志。开发人员希望然后[clone](/tutorials/setting-up-a-repository/git-clone) my-project.git
要在其开发计算机上创建一个本地副本。
git 克隆
的git clone
命令将复制现有的 Git 存储库。这就像是svn checkout
除了"工作副本"是一个正式的 Git 存储库 — — 它有它自己的历史、 管理它自己的文件,并是一个完全隔离的环境,从原始的存储库。
作为一种方便,自动克隆过程可以创建一个名为起源回指向原始存储库的远程连接。这使得它很容易与一个中央存储库进行交互。
使用
git clone <repo>
克隆存储库位于<repo>
到本地机器。原始的存储库可以位于本地文件系统上或可通过 HTTP 或 SSH 访问远程计算机上。
git clone <repo> <directory>
克隆存储库位于<repo>
到该文件夹中称为<directory>
在本地计算机。
讨论
如果已经在一个中央资料库,设置了一个项目git clone
命令是最常用的方法为用户获取发展副本。像git init
克隆通常是一个一次性的操作 — — 一旦开发人员已获得一个工作副本,通过他们本地的存储库中管理所有的版本控制操作和协作。
回购回购协作
它是重要的是理解的"工作副本"Git 的想法是非常不同于可以通过签出代码从 SVN 存储库中的工作副本。不像 SVN、 Git 使工作副本和中央存储库之间没有区别 — — 他们是所有成熟的 Git 仓库。
这使得勾结 Git 从根本上不同于与 SVN。而 SVN 取决于中央存储库和工作副本之间的关系,Git 的协作模型基于存储库存储库中的相互作用。而不是检查工作副本到 SVN 的中央存储库中,你推或拉从一个存储库提交到另一个。
当然,还有什么能阻止你给某些 Git 回购协议的特殊意义。例如,通过简单地将一个 git 存储库指定为"中央"的存储库,就可以复制使用 Git using Git. The point is, this is accomplished through conventions rather than being hardwired into the VCS itself.Centralized workflow
示例
下面的示例演示如何获取的中央存储库存储在可访问在服务器上的本地副本example.com
使用 SSH 用户名john:
git clone ssh://john@example.com/path/to/my-project.git
cd my-project
# Start working on the project
第一个命令初始化一个新的 Git 仓库中my-project
在本地计算机上的文件夹并在其中填充中央资料库的内容。然后,你可以cd
在项目里开始编辑文件、 犯下快照,以及与其他存储库进行交互。此外请注意,.git
从克隆库中省略了扩展。这反映了非裸状态的本地副本。
git 配置
的git config
命令允许您从命令行配置您的 Git 安装 (或个别的存储库)。此命令可以定义一切从用户信息行为的一个存储库首选项。下面列出了几种常用的配置选项。
使用
git config user.name <name>
定义用于在当前存储库中的所有提交的作者姓名。通常情况下,你会想要使用--global
要为当前用户设置配置选项标志。
git config --global user.name <name>
定义用于所有提交由当前用户的作者姓名。
git config --global user.email <email>
定义作者电子邮件用于所有提交由当前用户。
git config --global alias.<alias-name> <git-command>
创建一个 Git 命令的快捷方式。
git config --system core.editor <editor>
定义为当前计算机上的所有用户由像 git commit 命令使用文本编辑器。 < 编辑器 > 参数应启动所需的编辑器 (如 vi) 的命令。
git config --global --edit
在文本编辑器中打开全局配置文件,进行手动编辑。
讨论
所有配置选项都保存在纯文本文件,因此,git config
命令是真的只是一个方便的命令行界面。通常情况下,您只需要配置一个 Git 安装第一个时间你开始工作了新的发展机,和几乎所有的情况下,你会想要使用--global
标志。
Git 存储配置选项在三个单独的文件,使您可以到单个存储库、 用户或整个系统范围选项:
<repo>/.git/config
— — 存储库中特定的设置。~/.gitconfig
— — 用户特定的设置。这是在哪里与设置选项--global
存储标志。$(prefix)/etc/gitconfig
— — 系统范围的设置。
当这些文件中的选项冲突时,本地设置重写覆盖全系统的用户设置。如果您打开所有这些文件,您将看到类似于以下内容:
[user]
name = John Smith
email = john@example.com
[alias]
st = status
co = checkout
br = branch
up = rebase
ci = commit
[core]
editor = vim
您可以手动编辑这些值以完全相同的效果git config
.
示例
要安装 Git 后做的第一件事是告诉它邮箱名称,自定义某些默认设置。典型的初始配置可能看起来类似于以下内容:
# Tell Git who you are
git config --global user.name "John Smith"
git config --global user.email john@example.com
# Select your favorite text editor
git config --global core.editor vim
# Add some SVN-like aliases
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.up rebase
git config --global alias.ci commit
这将产生~/.gitconfig
前面的部分文件。
接下来:
保存更改
保存更改
git 添加
的git add
命令将在工作目录中的变更添加到暂存区域。它告诉 Git 你想要在下一次提交中包含到一个特定文件的更新。然而,git add
不会真正影响存储库中任何重大的方式 — — 不直到您运行实际记录更改git commit
.
配合这些命令,您还需要git status
若要查看工作目录和暂存区域的状态。
使用
git add <file>
所有阶段的都变化<file>
为下一次提交。
git add <directory>
所有阶段的都变化<directory>
为下一次提交。
git add -p
开始交互式的临时会话,允许您选择要添加到下一次提交的文件的某些部分。这将奉上一大块的变化,并提示您输入命令。使用y
舞台大块,n
要忽略块,s
要拆分成更小块,e
若要手动编辑块,和q
要退出。
讨论
的git add
和git commit
命令构成基本的 Git 工作流。这些都是每一个 Git 用户需要明白,无论他们团队的协作模型的两个命令。他们是如何进入存储库的历史记录项目的版本。
开发一个项目围绕着基本的编辑和阶段/提交模式。首先,您编辑您在工作目录中的文件。当你准备好要保存的项目的当前状态的副本时,你阶段的变化git add
.如果你满意上演快照后,将您提交与项目历史记录git commit
.
的git add
不将命令与相混淆svn add
其中将文件添加到存储库中。相反,git add
作品的更抽象的层次上更改。这意味着,git add
需要调用每次您更改一个文件,而svn add
只需要为每个文件调用一次。这可能听起来很多余,但此工作流使得它更容易保持组织的项目。
临时区域
暂存区是 Git 的更独特的功能之一,它可能需要一些时间来包装你的头在它附近,如果你来自一个 SVN (或甚至 Mercurial) 背景。它有助于把它想成工作目录和项目历史记录之间的缓冲区。
而不是提交所有自上次提交所做的更改,舞台让您在实际上将它提交项目历史记录之前分组相关的更改成高度集中的快照。这意味着你可以对无关的文件,进行各种编辑然后回去和拆分,他们为逻辑提交通过向舞台添加相关的更改和提交它们一片一片的。在任何修订控制系统中,至关重要的是创建原子提交,以便很容易跟踪 bug 和还原对与项目其余部分影响最小的更改。
示例
当你开始一个新项目,git add
服务相同的功能svn import
.若要创建当前目录初始提交,请使用下列两个命令:
git add .
git commit
一旦您得到您的项目设置运行,可以通过向路径添加新文件git add
:
git add hello.py
git commit
上面的命令也可以用于记录到现有文件的更改。再次,Git 不区分与已被添加到存储库中的文件中的更改的新文件中的临时更改。
git commit
的git commit
命令将上演的快照承诺项目历史记录。致力于的快照可以被认为是"安全"版本的项目 — — Git 将永远不会改变它们,除非您明确地问到。随着git add
这是最重要的 Git 命令之一。
虽然它们共享相同的名称时,此命令也不像svn commit
.快照是致力于本地资源库中,而这需要绝对没有互动与其他 Git 存储库。
使用
git commit
提交阶段性的快照。这将启动提示您输入提交消息的文本编辑器。您已经输入一条消息后,保存文件并关闭编辑器来创建实际的提交。git commit -m "<message>"
提交阶段性的快照,但而不是启动文本编辑器使用<message>
作为提交消息。
git commit -a
提交所有更改工作目录中的快照。这只包括跟踪文件 (那些已添加与修改git add
在其历史上的一些点)。
讨论
快照都致力于本地存储库。这是从根本上不同于 SVN,其中所述的工作副本是致力于中央存储库。与此相反的是,Git 不强迫你去与中央存储库进行交互,直到你准备好了。正如临时区域是工作目录和项目历史记录之间的缓冲区,每个开发人员的本地存储库是他们的捐款和中央存储库之间的缓冲。
这将更改 Git 用户的基本发展模式。而不是做一些改变,直接提交央企回购,Git 开发人员有机会积累在他们当地的回购承诺。这相比有着许多优点 SVN 风格协作: 它使它容易拆分成原子提交的功能、 保持组合在一起,有关的提交和发布到中央存储库之前清理本地历史记录。它还允许开发人员工作在孤立的环境中,推迟集成,直到他们在一个方便的破发点。
不差别的快照
除了 SVN、 Git 的实际区别,其底层的实现也遵循完全不同的设计理念。而 SVN 跟踪差异的一个文件,Git 的版本控制模型基于快照。例如,一个 SVN 提交包括 diff 相比,添加到存储库中的原始文件。Git,另一方面,记录整个内容的每个文件中每个 commit。
这使得许多 Git 操作比 SVN,快得多,因为一个文件的特定版本不需要"组装"从其差异 — — 每个文件完成修订可立即从 Git 的内部数据库。
Git 的快照模型对其版本控制模型,影响一切从其分支和合并到其协作工作流工具几乎每个方面具有深远的影响。
示例
下面的示例假定您已经编辑了称为文件中的一些内容hello.py
并准备将其提交到项目历史记录。首先,你需要阶段具有的文件git add
然后你可以提交阶段性的快照。
git add hello.py
git commit
这将打开一个文本编辑器 (通过定制git config
) 要求提交消息,以及什么是正在犯的列表:
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
#modified: hello.py
Git 不需要提交消息遵循任何特定的格式设置限制,但规范的格式是总结一下少于 50 个字符中的第一行时整个提交,留一个空白行,然后详细解释什么已更改。举个例子:
Change the message displayed by hello.py
- Update the sayHello() function to output the user's name
- Change the sayGoodbye() function to a friendlier message
请注意许多开发人员也喜欢在他们提交消息中使用现在时。这使得他们读的更像是使很多历史重写操作更直观的存储库中的操作。
接下来:
检查存储库
开始下一个教程
检查存储库
git 状态
的git status
命令显示工作目录和暂存区域的状态。它让你看到上演了哪些更改,哪些还没有,不由 Git 跟踪哪些文件。状态输出并 告诉你任何关于致力于的项目历史记录的资料。为此,您需要使用git log
.
使用
git status
列出哪些文件正在上演,满怀,和跟踪。
讨论
的git status
命令是一个相对简单的命令。它只是告诉你什么一直与git add
和git commit
.状态消息还包括分期/unstaging 文件的相关说明。示例的输出,显示三个主要的类别git status
调用包含如下:
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
#modified: hello.py
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
#modified: main.py
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
#hello.pyc
忽略文件
跟踪的文件通常分为两类。他们要么文件只是已添加到该项目,没有去过犯,或他们已编译的二进制文件喜欢.pyc
, .obj
, .exe
等等。虽然它是绝对有利,包括在前git status
输出,后者可以使它难看到您的存储库的实际状况。
为此,Git 允许您通过将路径放置在一个特殊的文件,称为完全忽略的文件.gitignore
。应在单独的行,包括任何你想要忽略的文件和 * 符号可以用作通配符。例如,添加到以下.gitignore
你项目的根目录中的文件会阻止编译的 Python 模块中出现git status
:
*.pyc
示例
它是很好的做法在提交更改,所以,你不要不小心犯下你不到的东西之前检查您的存储库的状态。此示例显示了存储库状态,分期和犯下快照之前和之后:
# Edit hello.py
git status
# hello.py is listed under "Changes not staged for commit"
git add hello.py
git status
# hello.py is listed under "Changes to be committed"
git commit
git status
# nothing to commit (working directory clean)
第一状态输出将显示为未缓存的文件。的git add
行动将反映在第二个git status
最终状态输出会告诉你没什么可承诺 — — 的工作目录匹配最新提交。一些 Git 命令 (例如,git merge
) 要求工作目录是干净的所以,你不要不小心覆盖变化。
git 日志
的git log
命令显示致力于的快照。它允许您列出项目历史记录并过滤它,搜索特定的更改。虽然git status
允许您检查工作目录和临时区域git log
仅致力于历史上进行操作。
在几个方面,从简单地筛选到完全由用户定义的格式显示它们的提交,可以自定义日志输出。一些最常见的配置git log
列示如下。
使用
git log
显示使用默认格式的整个提交历史记录。如果输出占了超过一个屏幕,您可以使用Space
若要滚动和q
要退出。
git log -n <limit>
限制数目由提交<limit>
.例如,git log -n 3
将显示只有 3 提交。
git log --oneline
凝聚每个致力于单个行。这是十分有用的项目历史记录的高级别概述。
git log --stat
随着普通git log
信息,包括哪些文件被修改的行添加或删除从他们每个人都相对数。
git log -p
显示代表每次提交该修补程序。这表明每个执行 commit 时,这是最详细的视图,你可以有你的项目历史记录的全面比较。
git log --author="<pattern>"
搜索由特定作者提交。的<pattern>
参数可以是一个简单的字符串或正则表达式。
git log --grep="<pattern>"
搜索提交与匹配的提交消息<pattern>
可以是一个普通字符串或正则表达式。
git log <since>..<until>
显示仅之间发生的提交<since>
和<until>
.这两个参数可以是任何提交 ID、 一个分支名、HEAD
,或任何其他种类的修订参考.
git log <file>
只显示包含指定的文件的提交。这是简单的方法,请参阅特定文件的历史记录。
git log --graph --decorate --oneline
需要考虑的几个有用选项。— — 图将在左手边的提交消息绘制在提交一个基于文本图形的标志。— — 装饰添加分支机构的名称或标记显示的提交。— — 台联机显示提交信息在单独的一行,使它更容易浏览提交一眼。
讨论
的git log
命令是探索一个存储库历史 Git 的基本工具。它是您的使用,当您需要查找特定版本的项目,找出变化的将介绍通过合并在功能分支,或看到哪个开发者人数有懈怠。
commit 3157ee3718e180a9476bf2e5cab8e3f1e78a73b7
Author: John Smith
最主要的是很简单 ;然而,第一行有必要加以解释。后 40 个字符的字符串commit
是长沙 1 提交内容的校验和。这有两个目的。首先,它确保提交的完整性 — — 如果它曾经被损坏,提交会生成不同的校验和。第二,它作为一个唯一的 ID,提交。
在诸如之类的命令可以使用这个 IDgit log <since>..<until>
指特定的提交。例如,git log 3157e..5ab91
将显示与提交之间的一切 ID3157e
和5ab91
。除了校验和,分支名称 (讨论分支模块) 和头关键字是指的个人提交其他常用方法。HEAD
总是指当前的承诺,是它的分支或特定提交。
~ 字符是有用的 commit 父级的相对参照。例如,3157e~1
指的是在之前的提交3157e
和HEAD~3
是当前提交的祖父母。
所有这些识别方法背后的理念是让您可以执行基于特定的提交操作。的git log
命令通常是这些交互作用的起始点,它可让您查找您想要使用的提交。
示例
使用一节提供的许多示例git log
但请记住几个选项可以组合成一个单一的命令:
git log --author="John Smith" -p hello.py
这将显示充分比较的约翰 · 史密斯已对文件所做的所有更改hello.py
.
在...语法是非常有用的工具,用于比较分支机构。下一个示例显示中的所有提交简要概述some-feature
这不是在master
.
git log --oneline master..some-feature
git 结帐
的git checkout
命令是三个不同职能: 签出文件,签出提交,并签出分支。在此模块中,我们只关心与前两种配置。
签出提交使整个工作目录匹配的提交。这可以用于查看您的项目为原来的状态而不改变您当前的状态,以任何方式。签出文件允许您查看该特定的文件,您的工作目录的其余部分留未触动过旧版本。
使用
git checkout master
返回到主分支上。在接下来的模块中,深入报道分支,但现在,你可以只把这作为一种方式回到项目的"当前"状态。
git checkout <commit> <file>
签出文件的以前版本。这将打开<file>
从一个精确拷贝到驻留在工作目录中<commit>
并将其添加到暂存区域。
git checkout <commit>
更新要匹配的指定的提交的工作目录中的所有文件。你可以使用 commit 散列或作为一个标记<commit>
参数。这会让你在一个分离的国家元首。
讨论
任何版本控制系统背后的整个想法是存储项目的"安全"副本,以便您不需要担心无可挽回地破坏你的代码基。一旦你建立了一个项目历史记录git checkout
是简单的方法来"加载"到你的开发机器上这些已保存的快照中的任何。
签出的旧的提交是一个只读的操作。它是无法同时查看旧修订版伤害您的存储库。您的项目的"当前"状态保持不变的master
分支 (请参阅分支机构模块的详细信息)。在正常的发展历程,HEAD
通常点船长或一些其他地方的分支,但是,当您签出之前的提交,HEAD
不再指向一个分支 — — 它直接指向一个提交。这就所谓的"分离HEAD
"状态,并且它可以被可视化为以下:
另一方面,签出旧的文件,并影响您的存储库的当前状态。任何其他文件一样,可以重新提交一个新的快照中的旧版本。实际上,这种用法的git checkout
作为恢复到旧版本的单个文件的方式。
示例
查看旧的版本
此示例假定您已经开始发展一个疯狂的实验,但你不知道,如果你想要保持它或不。为了帮助您做出决定,你想要来看看项目的状态,在你开始你的实验之前。首先,你需要找到您想要查看的修订 ID。
git log --oneline
假设您的项目历史看起来类似于以下内容:
b7119f2 Continue doing crazy things
872fa7e Try something crazy
a1e8fb5 Make some important changes to hello.py
435b61d Create hello.py
9773e52 Initial import
您可以使用git checkout
若要查看"让一些导入更改为 hello.py"承诺,如下所示:
git checkout a1e8fb5
这使您的工作目录匹配的确切状态a1e8fb5
提交。你可以看看文件、 编译该项目,运行测试,和甚至编辑文件,而不必担心丢失该项目的当前状态。什么你不在这里将被保存在您的存储库。若要继续发展,你需要回到你的项目的"当前"状态:
git checkout master
这是假设您正在开发的默认主分支,将分支机构模块中深入讨论了。
一旦你回到主分支,您可以使用git revert
或git reset
若要撤消任何发生意外的变化。
签出文件
如果你仅有兴趣在单一文件中,您还可以使用git checkout
获取旧版本的它。例如,如果您只想看到hello.py
文件从旧的提交,您可以使用下面的命令:
git checkout a1e8fb5 hello.py
请记住,与不同的签出的承诺,这没有会影响您的项目的当前状态。旧的文件版本将显示为"提交更改,"让你有机会恢复到以前版本的文件。如果您决定不想要保留旧版本,你可以检查出用以下的最新版本:
git checkout HEAD hello.py
撤消更改
本教程中提供了所有必要的技能,与以前的修订版本软件项目的工作。首先,它显示你如何发掘旧属然后它解释了在项目历史记录与重置未发布的更改本地计算机上的差异给恢复公共犯。
git 结帐
的git checkout
命令是三个不同职能: 签出文件,签出提交,并签出分支。在此模块中、 我们只关心与前两种配置。
签出提交使整个工作目录匹配的提交。这可以用于查看您的项目为原来的状态而不改变您当前的状态、 以任何方式。签出文件允许您查看该特定的文件、 您的工作目录的其余部分留未触动过旧版本。
使用
git checkout master
返回到主分支上。在接下来的模块中、 深入报道分支、 但现在、 你可以只把这作为一种方式回到项目的"当前"状态。
git checkout <commit> <file>
签出文件的以前版本。这将打开<file>
从一个精确拷贝到驻留在工作目录中<commit>
并将其添加到暂存区域。
git checkout <commit>
更新要匹配的指定的提交的工作目录中的所有文件。你可以使用提交散列或作为一个标记<commit>
参数。这会让你在一个分离的国家元首。
讨论
任何版本控制系统背后的整个想法是存储项目的"安全"副本,以便您不需要担心无可挽回地破坏你的代码基。一旦你建立了一个项目历史记录git checkout
is an easy way to “load” any of these saved snapshots onto your development machine.
Checking out an old commit is a read-only operation. It’s impossible to harm your repository while viewing an old revision. The “current” state of your project remains untouched in the master
branch (see the Branches Module for details). During the normal course of development, the HEAD
usually points to master or some other local branch, but when you check out a previous commit, HEAD
no longer points to a branch—it points directly to a commit. This is called a “detached HEAD
” state, and it can be visualized as the following:
On the other hand, checking out an old file does affect the current state of your repository. You can re-commit the old version in a new snapshot as you would any other file. So, in effect, this usage of git checkout
serves as a way to revert back to an old version of an individual file.
Example
Viewing an Old Revision
This example assumes that you’ve started developing a crazy experiment, but you’re not sure if you want to keep it or not. To help you decide, you want to take a look at the state of the project before you started your experiment. First, you’ll need to find the ID of the revision you want to see.
git log --oneline
假设您的项目历史看起来类似于以下内容:
b7119f2 Continue doing crazy things
872fa7e Try something crazy
a1e8fb5 Make some important changes to hello.py
435b61d Create hello.py
9773e52 Initial import
您可以使用git checkout
若要查看"让一些导入更改为 hello.py"承诺,如下所示:
git checkout a1e8fb5
这使您的工作目录匹配的确切状态a1e8fb5
提交。你可以看看文件、 编译该项目、 运行测试、 和甚至编辑文件、 而不必担心丢失该项目的当前状态。什么你不在这里将被保存在您的存储库。若要继续发展、 你需要回到你的项目的"当前"状态:
git checkout master
这是假设您正在开发的默认主分支、 将分支机构模块中深入讨论了。
一旦你回到主分支、 您可以使用git revert
或git reset
若要撤消任何发生意外的变化。
签出文件
如果你仅有兴趣在单一文件中、 您还可以使用git checkout
获取旧版本的它。如果您只想看到后点查询即可hello.py
文件从旧的提交,您可以使用下面的命令:
git checkout a1e8fb5 hello.py
请记住,与不同的签出的承诺,神奇世界都是说会影响您的项目的当前状态。"提交更改"让你有机会恢复到以前版本的文件。 旧的文件版本将显示为如果您决定不想要保留旧版本,你可以检查出用以下的最新版本:
git checkout HEAD hello.py
git 还原
的git revert
命令撤消提交的快照。但是,请不要删除提交的项目历史记录,计算出如何撤消更改介绍提交并追加新犯下与最终结果的内容。这可以防止失去你修订历史记录的完整性和可靠的协作是非常重要的历史,Git。
使用
git revert <commit>
生成一个新的交付将撤消所有中引入的更改<commit>
然后将其应用到当前分支。
讨论
当你想要从您的项目历史删除整个 commit 时,应使用还原。这是有用的例如,如果你正在跟踪 bug,找到它推出了一个单一的提交。而不是手动去搞定它,和犯下新的快照,您可以使用git revert
自动为你做这一切。
恢复与重置
很重要的是要理解这一点git revert
撤消单个的提交 — — 它不会"恢复"到以前的状态的一个项目,通过删除所有后续提交。在 Git 中,这实际上所谓的reset
不revert
.
还原已重置的两个重要优势。第一,它不会更改项目的历史记录,使它已经发布到一个共享的存储库中的提交的"安全"操作。为细节,关于为什么改变共享的历史上是危险的请参见git reset
页。
第二,git revert
而是能够针对个人在历史中,任意时间点提交git reset
仅能向后从当前提交。如果你想要撤消与旧的提交后点查询即可git reset
你必须删除所有发生在目标提交后提交,将其删除然后重新提交所有后续提交。不用说、 这不是优雅的撤消解决方案。
示例
下面的示例是一个简单的演示的git revert
.它属一个快照、 然后立即将其撤消与恢复。
# Edit some tracked files
# Commit a snapshot
git commit -m "Make some changes that will be undone"
# Revert the commit we just created
git revert HEAD
这可以被可视化为以下内容:
请注意,第 4 次提交仍处于恢复后项目历史记录。而不是删除它,git revert
添加一个新的交付、 以撤消其更改。看见、 第 3 和第 5 次提交代表确切相同的代码库、 和第 4 次提交是仍然在我们的历史、 以防万一我们想给它沿着这条路。
git 重置
如果git revert
若要撤消更改,"平安"是你能想到的git reset
作为被解雇方法。当您撤消与git reset
(和承诺不再被引用的任何 ref 或 reflog),那里是没有检索的原始副本的方法 — — — — 它是常任理事国撤消。时使用这个工具,因为它是一个唯一的 Git 命令,有可能失去你的工作,必须特别小心。
译英git checkout
, git reset
是一个多才多艺的命令,与多个配置。它可用于删除提交的快照,虽然它更经常用于撤消更改临时区域中的工作目录。在任一情况下,它应该只用于撤消当地的变化 — — 你应该永远不会重置已与其他开发人员共享的快照。
使用
git reset <file>
删除指定的文件从临时区域中,但离开工作目录保持不变。这 unstages 文件而不会覆盖任何更改。
git reset
重置暂存区域匹配的最新的提交,但是要保留不变的工作目录。这 unstages 所有文件而不会覆盖任何更改,让你有机会重新生成从零开始上演的快照。
git reset --hard
重置暂存区域并要匹配最新提交的工作目录。除了 unstaging 的变化,--hard
标志告诉 Git 太覆盖在工作目录中的所有更改。换一种说法: 这抹杀所有未提交的更改,所以确保你真的想要扔掉你当地的事态发展之前使用它。
git reset <commit>
移动当前的枝梢落后到<commit>
重置暂存区域匹配,而是独自一人离开工作目录。以来所做的所有更改<commit>
将驻留在工作目录中,让您重新提交项目历史记录使用更清洁、 更多的原子快照。
git reset --hard <commit>
移动当前的枝梢落后到<commit>
和重置临时区域和要匹配的工作目录。这抹杀不仅未提交的更改、 但所有提交后<commit>
以及。
讨论
所有上述调用用于从存储库中移除的更改。都是说--hard
旗帜,git reset
是,清理存储库通过 unstaging 的变化或 uncommitting 一系列的快照并重新建设他们从零开始。的--hard
当实验有了可怕的错误,你需要一个干净的石板上班与旗会派上用场。
而恢复为了安全地撤消公共执行 commit 时,git reset
旨在撤消定位的变化。由于其独特的目标,这两个命令的实现方式不同: 完全重置删除变更集,而还原维护原始变更集并使用新的提交申请撤消。
不重置公共历史
你不应该使用git reset <commit>
当任何快照后的< > 提交已经被推向一个公共存储库。在发布后提交、 你不得不假设其他开发人员依赖它
删除其他团队成员有继续发展的提交、 在协作时将认真大的问题。当他们尝试与您的存储库的同步时、 它将看起来像一块的项目历史记录突然消失了。下面的序列演示当您尝试重置公众提交时、 会发生什么。的origin/master
分支是您当地的中央存储库的版本master
分支。
尽快在重置后,您将添加新的提交,Git 将认为您本地历史记录已分道扬镳origin/master
并同步您的存储库所需的合并提交有可能感到困惑和沮丧你的团队。
关键是,请确保您正在使用git reset <commit>
走错了地方的实验 — — 不是在发布的更改。如果你需要修复公共执行 commit 时,git revert
命令是专为此目的而设计的。
例子
Unstaging 文件
的git reset
准备上演的快照时频繁地遇到命令。下一个示例假定您有两个文件叫hello.py
和main.py
表示您已经已经添加到存储库。
# Edit both hello.py and main.py
# Stage everything in the current directory
git add .
# Realize that the changes in hello.py and main.py
# should be committed in different snapshots
# Unstage main.py
git reset main.py
# Commit only hello.py
git commit -m "Make some changes to hello.py"
# Commit main.py in a separate snapshot
git add main.py
git commit -m "Edit main.py"
正如你所看到的git reset
可以帮助您保持您的提交高度集中,让你 unstage 不到下一次提交相关的更改。
删除本地提交
下面的示例演示一个更高级的用例。它表明你已经在一段时间,一个新的实验,但决定去完全把它扔掉后犯下几张照片的过程中会发生什么。
# Create a new file called `foo.py` and add some code to it
# Commit it to the project history
git add foo.py
git commit -m "Start developing a crazy feature"
# Edit `foo.py` again and change some other tracked files, too
# Commit another snapshot
git commit -a -m "Continue my crazy feature"
# Decide to scrap the feature and remove the associated commits
git reset --hard HEAD~2
的git reset HEAD~2
命令将移动当前分支落后两次提交,有效地去除我们刚才从项目历史记录中创建这两个快照。记住这种重置应该只用上未发布的 ,即属。永远不会执行上述操作,如果你已经把你提交到一个共享的存储库。
git 清洁
的git clean
命令从您的工作目录中移除跟踪的文件。这是命令的真的更多的方便,因为它是命令的琐碎,看看哪些文件是命令的与跟踪git status
和手动删除它们。像一个普通的rm
命令,git clean
是不可撤消的所以请确保你真的想要删除你在运行它之前的跟踪的文件
的git clean
配合经常执行命令git reset --hard
.请记住仅重置到单独的命令就要求清理未跟踪的影响跟踪的文件。这两个命令相结合,让您的工作目录返回到一个特定的提交的确切状态。
使用
git clean -n
执行 git 清洁"干运行"。这会告诉你哪些文件要删除实际上并不做它。
git clean -f
从当前目录中删除跟踪的文件。的-f
(力) 标志是必需的除非clean.requireForce
配置选项设置为false
(它有true
默认情况下)。这将不会删除跟踪的文件夹或通过指定的文件.gitignore.
git clean -f <path>
删除跟踪的文件,但限制到指定的路径操作。
git clean -df
删除跟踪的文件和跟踪从当前目录的目录。
git clean -xf
删除当前目录,以及通常忽略了 Git 的任何文件的跟踪的文件。
讨论
的git reset --hard
和git clean -f
您在本地资源库中做一些令人尴尬的事态发展,并想要刻录的证据后,命令是你最好的朋友。运行他们俩会使您的工作目录匹配的最新的提交、 给你一个干净的石板,与工作。
的git clean
命令还可用于在生成后清理的工作目录。例如,它可以轻松地删除.o
和.exe
由 C 编译器生成的二进制文件。在打包发布一个项目之前,这是偶尔一个必要的步骤。的-x
选项是为此目的特别方便。
保持记住那,相处git reset
, git clean
是具有潜力来永久删除提交,所以要小心,因为它的唯一的 Git 命令之一。事实上,它是很容易失去重要补充,Git 维护要求 -f
甚至最基本的操作的标志。这可以防止您意外地删除一切与天真git clean
调用。
示例
下面的示例涂掉包括已添加的新文件的工作目录中的所有更改。它假定你已经犯了几个快照,并正在尝试一些新的事态发展。
# Edit some existing files
# Add some new files
# Realize you have no idea what you're doing
# Undo changes in tracked files
git reset --hard
# Remove untracked files
git clean -df
在运行此重置/清洁的序列之后, 工作目录和临时区域将一模一样的最新的提交、 和git status
将报告一个干净的工作目录。现在,您已准备好重新开始。
注意到,与不同的是在第二个示例git reset
新的文件,本书根本不_added 到存储库。其结果是、 他们可能不会受git reset --hard
和git clean
需要删除它们。
改写历史
介绍
Git 的主要工作是要确保你永远不会丢失已提交的更改。但是,它同时也是为了让您在您的开发工作流的完全控制。这包括让您定义确切地是什么您的项目历史样子 ;然而,它还创建可能遭受损失提交。Git 提供其历史重写命令下使用它们可能会导致丢失内容的免责声明。
本教程讨论了一些覆盖致力的快照的最常见原因,并显示你如何避免这样做。
git 提交--修订
的git commit --amend
命令是一个方便的方法来解决最近提交了。它允许您阶段性的变化结合之前的提交,而不是提交作为一个完全新的快照。它也可以用于只需编辑以前提交消息,而无需更改其快照。
但修订并不只是改变最近提交 — — 是完全替换了它。到 Git,它会看起来像全新的提交,则显示为星号 (*) 在上面的图。很重要的是要记住这一点,当工作与公共存储库。
使用
git commit --amend
结合上一次提交的阶段性的变化和上次提交替换所生成的快照。这个运行时上演的什么都不允许您编辑以前提交消息而不改变其快照。
讨论
过早提交发生在你日常的发展过程中的所有时间。它很容易忘记阶段文件或者格式化您的提交消息错误的方式。的--amend
国旗是简便的方法来修复这些小错误。
不要修改公共提交
对git reset
页面上,我们谈论如何你应该永远不会重置已与其他开发人员共享的提交。这同样适用于修正: 永远不会修改已经被推向一个公共版本库的提交。
实际上完全新的提交,并修订的提交上次提交从项目历史记录中删除。这已重置公众的快照相同的后果。如果你修改提交,其他开发人员有基于他们的工作,它会看起来像他们工作的基础从项目历史记录里消失了。这是一个令人困惑的局面,开发人员需要在和它很复杂,从恢复。
示例
下面的示例演示 Git 为基础的发展中的一个常见场景。我们编辑我们想要在一个单一的快照,犯下的几个文件,但之后我们忘了添加一个文件的第一次。修复错误只是暂存另一个文件并与犯--amend
标志:
# Edit hello.py and main.py
git add hello.py
git commit
# Realize you forgot to add the changes from main.py
git add main.py
git commit --amend --no-edit
编辑器将填充来自上次提交的消息,包括--no-edit
国旗将让您可以向您提交修订而不改变其提交消息。你可以改变它,如果必要,否则为只是保存并关闭该文件像往常一样。由此产生的提交将替换不完整的和它将看起来像我们承诺的变化hello.py
和main.py
在单个快照。
git rebase
重订基期是将一个分支移到一个新的基地交付的过程。一般的过程可以被可视化为以下内容:
从内容的角度来看,重订基期真的只一个分支从移动一次提交到另。但在内部,Git 完成这通过创建新的提交,并将它们应用到指定的基 — — 这从字面上重写您的项目历史。它是非常重要的是要明白即使分支看起来相同,它组成的完全新的提交。
使用
git rebase <base>
变基到当前分支< 基地 >,可以是任何一种提交参考 (ID、 分支名称、 标记或对相对引用HEAD
).
讨论
重订基期的主要原因是保持线性项目历史记录。例如,请考虑主分支已在功能上开始工作之后的情况:
有两个选项可用于集成到您的功能master
分支: 直接合并或重订基期,然后合并。前一种选择结果 3 种方式合并,合并提交,而后者结果在快进合并和完美的线性的历史。下面的关系图演示如何到基址master
便于快进合并。
重订基期是常见的方式,将上游的改动纳入本地资源库。拉动上游的变化git merge
在每次您想要查看的项目的进展如何的多余合并提交的结果。另一方面,重订基期是像是在说,"我想要我的变化的基础每个人都已经所做的是什么"。
不重订公共历史
正如我们已经讨论与git commit --amend
和git reset
你应该永远不会变基已经被推向一个公共版本库的提交。Rebase 将以新的取代旧的提交,它会看起来像您的项目历史那部分突然消失了。
例子
下面的示例结合 git rebase git 合并,以保持线性项目历史记录。这是一种确保您合并将是节目的快速简便的方法。
# Start a new feature
git checkout -b new-feature master
# Edit files
git commit -a -m "Start developing a feature"
在我们的特色,我们意识到我们的项目有一个安全漏洞
# Create a hotfix branch based off of master
git checkout -b hotfix master
# Edit files
git commit -a -m "Fix security hole"
# Merge back into master
git checkout master
git merge hotfix
git branch -d hotfix
合并后该修补程序的主人,我们有分叉的项目历史记录。而不是平原 git 合并,我们会把他们的特性分支结合 rebase 能够保持一个线性的历史:
git checkout new-feature
git rebase master
这将新功能移到尖端的主人,让我们做一个标准的快进合并从主服务器:
git checkout master
git merge new-feature
git rebase-i
运行git rebase
与-i
国旗开始基址的交互式会话。而不是盲目地移动所有提交到新基地,交互式基期给你的机会来改变个人提交过程中。这允许您通过删除、 拆分,并改变现有系列的提交清理历史。这就像git commit --amend
注射了类固醇。
使用
git rebase -i <base>
变基到当前分支<base>
但使用基址的交互式会话。这为每个提交基期打开编辑器,您可以在其中输入命令 (如下所述)。这些命令确定如何个人即属将转移到新的基地。您还可以重新安排提交清单更改提交自己的顺序。
讨论
交互式基期给您完全控制您的项目历史是什么样子。这给开发人员,提供很大的自由,因为它让他们犯下"的混乱"的历史,虽然他们专注于编写代码,然后回去和事后清理它。
大多数开发人员喜欢使用交互式 rebase 抛光特性分支合并到主代码库中之前。这给了他们机会壁球微不足道的提交,删除过时的并确保其他的一切都是为了给"官方"的项目历史记录之前。对其他人来说,它会像整个特征开展了周密提交单一系列。
例子
找到下面的例子是一个从非交互式互动适应git rebase
页。
# Start a new feature
git checkout -b new-feature master
# Edit files
git commit -a -m "Start developing a feature"
# Edit more files
git commit -a -m "Fix something from the previous commit"
# Add a commit directly to master
git checkout master
# Edit files
git commit -a -m "Fix security hole"
# Begin an interactive rebasing session
git checkout new-feature
git rebase -i master
最后一个命令将打开编辑器填充从新功能以及一些说明的两个承诺:
pick 32618c4 Start developing a feature
pick 62eed47 Fix something from the previous commit
您可以更改每个提交前的挑命令,以确定它如何获取移动在 rebase 期间。在我们的例子,让我们只是结合两次提交一个壁球命令:
pick 32618c4 Start developing a feature
squash 62eed47 Fix something from the previous commit
保存并关闭编辑器开始 rebase。这将打开另一个编辑器中寻求合并的快照的提交消息。定义提交消息之后, rebase 是完整,你应该能够看到被压扁的犯在你git log
输出。这整个的过程如下:
请注意被压扁的提交具有不同的 ID,比原来的承诺,告诉我们它确实是一个全新的提交。
最后,你可以快进合并,以融入主代码库的抛光的特性分支:
git checkout master
git merge new-feature
交互式重订基期的真正力量可以见于产生的主分支的历史 — — 额外的62eed47
提交是无处可寻。对其他人来说,它看起来像你是聪明的开发人员实现的人new-feature
同属第一次的完美量。这是如何互动的基期可以保持干净和有意义的项目历史记录。
git reflog
Git 跟踪的尖端的分支机构使用一种称为 reflog 机制的更新。这允许您回到变更集,即使他们未引用的任何分支或标记。后改写历史,reflog 包含分支的旧状态信息,并允许您回到那种状态,如有必要。
使用
git reflog
表明 reflog 的本地资源库。
git reflog --relative-date
显示与相对日期信息 (例如 2 周前) reflog。
讨论
每次当前头获取更新 (通过切换分支,拉新的变化,改写历史或简单地通过添加新的提交) 一个新的条目将添加到 reflog 中。
示例
要了解git reflog
让我们看一个示例。
0a2e358 HEAD@{0}: reset: moving to HEAD~2
0254ea7 HEAD@{1}: checkout: moving from 2.2 to master
c10f740 HEAD@{2}: checkout: moving from master to 2.2
Reflog 上述显示签出从硕士到 2.2 分支和背部。从那里,有一个年长的提交到硬重置。最近的活动表示顶部标有HEAD@{0}
.
如果事实证明你意外搬回来,reflog 将包含指向 (0254ea7) 之前你意外下降 2 提交, 提交硕士。
git reset --hard 0254ea7
使用git reset
它是然后可能要回到以前提交更改母版。这提供一个安全网,以防被意外更改历史。
它是重要的地注意到 reflog 只提供一个安全网,如果更改已致力于您的本地存储库,它只跟踪运动。
原英文网址为:https://www.atlassian.com/git/tutorials/rewriting-history/git-reflog