diff --git a/translated/tech/20221121.2 ⭐️⭐️ Learn Git 3 commands to level up your skill.md b/translated/tech/20221121.2 ⭐️⭐️ Learn Git 3 commands to level up your skill.md index c7d65c0a8f..94dbb6f291 100644 --- a/translated/tech/20221121.2 ⭐️⭐️ Learn Git 3 commands to level up your skill.md +++ b/translated/tech/20221121.2 ⭐️⭐️ Learn Git 3 commands to level up your skill.md @@ -3,110 +3,118 @@ [#]: author: "Dwayne McDaniel https://opensource.com/users/dwaynemcdaniel" [#]: collector: "lkxed" [#]: translator: "chai001125" -[#]: reviewer: " " +[#]: reviewer: "wxy" [#]: publisher: " " [#]: url: " " -学习 3 个 Git 命令来提高你的能力 +掌握强大的 Git 变基命令 ====== -当我与别人谈到 Git 时,几乎每个人都对 [`git rebase` 命令][1] 有强烈的印象,这个命令让许多人遇到了问题,而不得不更改目录、删除仓库、然后再重新克隆一个仓库。我认为这是因为他们误解了分支是如何工作,遇到了一个非常糟糕的默认界面,并搞砸了一些合并冲突。 +![][0] -### 怎么找不到 `Git squash` 命令? +> 学习如何使用 Git 来压扁、变基和精选。 -如果你曾在本地的仓库提交过很多次,并希望能把这些提交都压缩为 **一个提交** commit ,接下来,我们就来介绍能用什么 Git 命令达到这个目的。Git 称这个概念为 “**压缩提交**” squash commits 。我在处理文档时发现了这个概念:我花了十几个提交才修改好我的文档,但是仓库的维护者不想看到我所有的提交,以免都扰乱了该项目的历史,所以我被告知“需要压缩你的提交”。 +当我与别人谈到 Git 时,几乎每个人都对 [git rebase 命令][1] 有强烈的印象,这个命令让许多人遇到了问题,而不得不更改目录、删除仓库、然后再重新克隆一个仓库。我认为这是因为他们误解了分支是如何工作,遇到了一个非常糟糕的默认界面,还有一些合并冲突把事情搞得一团糟。 -**压缩提交**听起来是一个很有用的方法。但是只有一个问题:我不知道该怎么做。作为 Git 的新手,我做了任何人会做的事情:我查阅了 `git-squash` 的手册,但我立即遇到了障碍: +### 怎么找不到 git squash 命令? + +如果你曾在本地的仓库提交过很多次,并希望能把这些提交都合并为一个提交,接下来,我们就来介绍能用什么 Git 命令达到这个目的。Git 称这个概念为 “压扁提交 squash commits ”。我在编写文档时发现了这个概念:我花了十几个提交才修改好我的 Markdown 文档,但是仓库的维护者不想看到我的所有尝试,以免扰乱了该项目的历史,所以我被告知“需要压扁你的提交”。 + +**压扁提交**听起来是一个很有用的方法。但是只有一个问题:我不知道该怎么做。作为 Git 的新手,我做了任何人会做的事情:我去查阅 `git-squash` 的手册,但我立即遇到了阻碍: ``` $ man git-squash > No manual entry for git-squash ``` -我发现没有一个名为 `squash` 的 Git 命令,而是被要求 [运行一个完全独立的命令:`git-rebase` 命令][2],该命令能将我的所有提交最终合并为一个提交。 +我发现没有一个名为 `squash` 的 Git 命令,而是被要求 [运行一个完全独立的命令:git rebase 命令][2],该命令能将我的所有提交最终合并为一个提交。 我知道我碰到一个常见的情形:已经使用工具一段时间的人使用了**行话**或引用了一个概念,这个概念对他们来说是非常清楚的,但对新手来说就不能明白了。从概念上讲,这个情况看起来是这样的: ![Image of 6 bowls of different colored spices, and an arrow pointing to the second image of all the spices blended into one bowl.][3] -我这样说是为了鼓励你,你绝对不是第一个或最后一个 _被 Git 或谈论 Git 的人_ 弄糊涂的人。你可以要求对方说明白他的意见,并帮助你应该使用的正确命令。仓库的维护者实际上的意思是,“使用 **`Git rebase` 命令**,将很多提交压缩成一个提交”。 +我这样说是为了鼓励你,你绝对不是第一个或最后一个 _被 Git 或谈论 Git 的人_ 弄糊涂的人。你可以要求对方说明白他的意见,并帮助你应该使用的正确命令。仓库的维护者实际上的意思是,“使用 `git rebase` 命令**,将很多提交压扁成一个提交”。 -### 现在就来学习 `Git rebase` 命令吧 +### 现在就来学习 git rebase 命令吧 -`git rebase` 命令会从其第一个父级中删除一个提交链,并将其放置在另一个提交链的末尾,将两个提交链组合成一个长链,而不是两个并行链。我意识到这是一个很复杂的定义。 +`git rebase` 命令会将一个提交链从其第一个父级中删除,并将其放置在另一个提交链的末尾,将两个提交链组合成一个长链,而不是两个并行链。我意识到这是一个很复杂的定义。 -回想一下 Git 提交是如何链接在一起的,你可以看到,除了初始的 `main` 分支外,任何分支都有一个 父提交 parent commit 作为该链的 “基础” base **变基** rebase 能使另一个链中的最后一个提交成为指定分支的新 “基础”提交 base commit 。 +回想一下 Git 的提交是如何链接在一起的,你可以看到,除了初始的 `main`(或 `master`)分支外,任何分支都有一个 父提交 parent commit 作为该链的 “基础 base ”。“变基 rebase ” 能使另一个链中的最后一个提交成为指定分支的新 “基础提交 base commit ”。 -在 Git 中整合来自不同分支的修改主要有两种方法:**merge** 以及 **rebase**,你可能更熟悉 `Git merge` 命令。接下来,就来看看 [git-scm.com] 是如何解释 `Git merge` 和 `Git rebase` 的差异: +在 Git 中整合来自不同分支的修改主要有两种方法:合并merge 以及 变基rebase,你可能更熟悉 `git merge` 命令。接下来,就来看看 [git-scm.com] 是如何解释 `git merge` 和 `git rebase` 的差异: ![Image of Git merge versus git rebase shown as numbered bubbles.][5] -在 **merge** 示例中,它会把两个分支的最新快照(C3 和 C4)以及二者最近的共同祖先(C2)进行三方合并,合并的结果是生成一个新的快照(C5)。“experiment”的分支指针仍然存在,仍然指向 C4。 +在合并示例中,它会把两个分支的最新快照(`C3` 和 `C4`)以及二者最近的共同祖先(`C2`)进行三方合并,合并的结果是生成一个新的快照(`C5`)。`experiment` 的分支指针仍然存在,仍然指向 `C4`。 -在 **rebase** 示例中,它提取在 C4 中引入的补丁和修改,然后在 C3 的基础上应用一次,使 C3 成为 C4 的新父级,并产生了一个名为 C4' 的新提交。 +在变基示例中,它提取在 `C4` 中引入的补丁和修改,然后在 `C3` 的基础上应用一次,使 `C3` 成为 `C4` 的新父级,并产生了一个名为 `C4'` 的新提交。 (LCTT 译注:具体的命令如下: + ``` $ git checkout experiment $ git rebase main First, rewinding head to replay your work on top of it... Applying: added staged command ``` -它的原理是首先找到这两个分支(即当前分支 experiment、变基操作的目标基底分支 main)的最近共同祖先 C2,然后对比当前分支相对于该祖先的历次提交,提取相应的修改并存为临时文件,然后将当前分支指向目标基底 C3, 最后以此将之前另存为临时文件的修改依序应用。) -值得注意的是,分支指针“main”没有移动。要让 Git 将指针移动到链的末尾(由“experiment”指向),你还需要执行合并。 +它的原理是首先找到这两个分支 —— 即当前分支 `experiment`、变基操作的目标基底分支 `main` —— 的最近共同祖先 `C2`,然后对比当前分支相对于该祖先的历次提交,提取相应的修改并存为临时文件,然后将当前分支指向目标基底 `C3`,最后以此将之前另存为临时文件的修改依序应用。) + +值得注意的是,分支指针 `main` 没有移动。要让 Git 将指针移动到链的末尾(由`experiment` 指向),你还需要执行合并。 (LCTT 译注:具体的命令如下: + ``` $ git checkout main $ git merge experiment ``` + ![master 分支的快进合并](https://www.progit.cn/images/basic-rebase-4.png) -此时,C4' 指向的快照就和上面使用 merge 命令的例子中 C5 指向的快照一模一样了。) +此时,`C4'` 指向的快照就和上面使用 `merge` 命令的例子中 `C5` 指向的快照一模一样了。) -`Git rebase` 并不能替代 `Git merge`。`Git rebase` 是一种用于制作更清晰的历史记录,以与 `Git merge` 结合使用的工具。 +`git rebase` 并不能替代 `git merge`。`git rebase` 是一种用于制作更清晰的历史记录,以与 `git merge` 结合使用的工具。 -(LCTT 译注:使用 `Git rebase` 命令将提交到某一分支上的所有修改都移至另一分支上,就好像“重新播放”一样。) +(LCTT 译注:使用 `git rebase` 命令将提交到某一分支上的所有修改都移至另一分支上,就好像“重新播放”一样。) -#### 交互式重基 Interactive rebase 能给你一个更友好的界面! +#### 交互式变基能给你一个更友好的界面! -从命令行执行 `Git rebase` 命令,最可怕的地方在于它**糟糕的默认界面**。运行命令 `git rebase ` 要么有效,要么会变得一团糟,因为它没有太多的反馈或方法来确保它做你想做的事情。幸运的是,`Git rebase` 命令和许多其他 Git 命令一样,具有 **交互模式** interactive mode ,你可以使用参数 `-i` 或者 `-interactive` 来使用交互模式。 +从命令行执行 `git rebase` 命令,最可怕的地方在于它**糟糕的默认界面**。运行命令 `git rebase ` 要么有效,要么会变得一团糟,因为它没有太多的反馈或方法来确保它做你想做的事情。幸运的是,`git rebase` 命令和许多其他 Git 命令一样,具有 交互模式 interactive mode ,你可以使用参数 `-i` 或者 `-interactive` 来使用交互模式。 ![Image of the Git lens interactive Rebase tool in VS Code.][6] -在使用交互式模式时,`Git rebase` 会从一个糟糕的黑框界面转换为一个**选项菜单**,允许你选择对正在重基的提交链所做的事。对于每个提交,你可以**选择**: +在使用交互式模式时,`git rebase` 会从一个糟糕的黑框界面转换为一个**选项菜单**,允许你选择对正在变基的提交链所做的事。对于每个提交,你可以**选择**: -- Pick:按原样包含 -- Reword:重写提交消息 -- Edit:在重基完成之前对提交中的文件进行进一步更改 -- Squash:将多个提交压缩成一个提交,保留所有提交消息 -- Fixup:将多个提交压缩成一个提交,但只保留最后一个提交消息 -- Drop:丢弃此提交 +- 选用pick:按原样包含 +- 重写reword:重写提交消息 +- 编写edit:在变基完成之前对提交中的文件进行进一步更改 +- 压扁squash:将多个提交压缩成一个提交,保留所有提交消息 +- 修理fixup:将多个提交压缩成一个提交,但只保留最后一个提交消息 +- 丢弃drop:丢弃此提交 就我个人而言,我更喜欢 [VS Code 的开源 GitLens 扩展][7] 使用下拉选择列表布局选项的方式,但 Git 允许你使用任何编辑器选择这些选项。对于 Emacs 或 Vim 等纯文本工具,你需要键入选择,而不是从菜单中选择,但最终结果仍然是相同的。 -#### 何时做 `Git rebase` +#### 何时做变基 -知道 _何时_ 做重基与知道 _如何_ 做重基同样重要。事实上,如果你不在乎你的仓库历史提交消息有点混乱的话,那么你可以永远都不使用 `Git rebase` 命令。但是,如果你想要更干净的历史提交消息,并且想要更少扰乱你的图形视图的提交,那么当你使用 `Git rebase` 命令时,有一个重要的**经验法则**需要时刻记住: +知道 _何时_ 做变基与知道 _如何_ 做变基同样重要。事实上,如果你不在乎你的仓库历史提交消息有点混乱的话,那么你可以永远都不使用 `git rebase` 命令。但是,如果你想要更干净的历史提交消息,并且想要更少扰乱你的图形视图的提交,那么当你使用 `git rebase` 命令时,有一个重要的**经验法则**需要时刻记住: -> “不要重基你存储库以外的以及人们可能要用的提交。” Do not rebase commits that exist outside your repository and that people may have based work on. +> “不要变基你存储库以外的的提交,那些提交可能是别人工作的基础。” 如果你遵循该准则,不会发生什么大问题的。 -简而言之,如果你让一个**本地分支**来完成你的工作,重基是没有问题的。但一旦该分支被 推送 push 了,就不要再重基该分支了。当然,你想要怎么做完全取决于你自己。 +简而言之,如果你让一个**本地分支**来完成你的工作,变基是没有问题的。但一旦该分支被 推送 push 了,就不要再变基该分支了。当然,你想要怎么做完全取决于你自己。 -希望你会认为上述内容有助于你理解 `Git rebase` 命令的工作原理,并能让你更有信心地使用它。与任何 Git 命令一样,**练习**是学习和理解怎么做的唯一方法。我鼓励你勇敢地尝试 交互式重基 interactive rebase `git rebase -i `! +希望你会认为上述内容有助于你理解 `git rebase` 命令的工作原理,并能让你更有信心地使用它。与任何 Git 命令一样,**练习**是学习和理解怎么做的唯一方法。我鼓励你勇敢地尝试 交互式变基 interactive rebase `git rebase -i `! -### 接下来学习 `Git cherry-pick` 命令吧 +### 接下来学习 Git cherry-pick 命令吧 -大多数开发人员将修改提交到某一分支上,但是之后发现他们一直**提交到了错误的分支上**。理想情况下,他们可以拿起那个提交,然后把它移到正确的分支,这正是 `git cherry-pick` 命令的作用。 +大多数开发人员将修改提交到某一分支上,但是之后发现他们一直**提交到了错误的分支上**。理想情况下,他们可以拿走那个提交,然后把它移到正确的分支,这正是 `git cherry-pick` 命令的作用。 -`git cherry-pick` 命令利用了重基单个提交的方法。这一用法非常常见,以至于有了它自己的命令。 +`git cherry-pick` 命令利用了变基单个提交的方法。这一用法非常常见,以至于有了它自己的命令。 ![Image of a woman picking a cherry from one tree and putting on another tree.][8] -要使用 `git cherry-pick`,你只需告诉 Git 你要移动到“那个分支”的提交 ID(由 HEAD 指向): +要使用 `git cherry-pick`,你只需告诉 Git 你要移动到“那个分支”的提交 ID(由 `HEAD` 指向): ``` $ git cherry-pick @@ -128,7 +136,7 @@ hint: run "git cherry-pick --abort". $ git cherry-pick --abort ``` -### Git more power +### 让 Git 更强大 `git rebase` 命令是 Git 实用程序强大的地方之一。你最好在测试仓库中先练习一下怎么使用,一旦你熟悉了它的概念和工作流程,你就可以给仓库一个清晰历史消息记录了。 @@ -139,7 +147,7 @@ via: https://opensource.com/article/22/11/advanced-git-commands 作者:[Dwayne McDaniel][a] 选题:[lkxed][b] 译者:[chai001125](https://github.com/chai001125) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 @@ -153,3 +161,4 @@ via: https://opensource.com/article/22/11/advanced-git-commands [6]: https://opensource.com/sites/default/files/2022-11/gitbeyond2.GitLens%20Interactive%20Rebase%20tool%20in%20VS%20Code.png [7]: https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens [8]: https://opensource.com/sites/default/files/2022-11/gitbeyond2.cherrypicking.png +[0]: https://img.linux.net.cn/data/attachment/album/202212/07/133637yq2526zsp7f1t7a2.jpg \ No newline at end of file