42 个 Git 问题解答
-
您最喜欢的 Git 命令是什么?
我非常喜欢
git add -p
。它会在内置的命令行程序“补丁模式”中添加更改。它会迭代我的每一项更改,并询问我是否要暂存它们。这个命令迫使我放慢速度,仔细检查我的修改。作为开发人员,我们常常匆匆忙忙地完成这一步,以为工作已经完成了。我都记不清有多少次我
git add .
匆匆忙忙地跑完,后来才意识到自己提交了“临时”文件或调试语句。 -
为什么您更喜欢从命令行使用 Git?
作为开发人员,我们已经使用命令行做了很多其他事情。为什么不也使用 Git 呢?
此外,Git 的命令集非常精简,对于开发人员来说非常容易学习,并且直接使用它可以改善您的开发工作流程。
-
我们如何使用
stage
命令?stage
是 的内置别名add
。 -
如何保存分支中的更改并检出到其他分支?
因此,您可以用它
git stash
来临时存储更改或进行 WIP 提交。目标是获得一个干净的工作索引。就我个人而言,我更喜欢使用 WIP 提交,而不是
stash
。我发现它们更容易引用和共享。 -
我什么时候应该使用
git stash
?我喜欢使用它来快速清理
stash
“工作索引” 。 -
如何了解如何使用 Git 命令?
对任何命令使用该
--help
选项。例如,git stash --help
。 -
什么是“git flow”?
git flow 是一种分支策略,使用多个“长寿命”分支来反映软件开发生命周期。根据需要,这些分支之间的更改会被合并。
-
什么是“GitHub Flow”?
基本上,GitHub Flow 是 /feature 分支工作流的品牌名称
master
。GitHub 使用其工具集将其正式化为流程,如本可视化教程所示。 -
您更喜欢哪种分支策略?
我参与过数百个 Git 项目,可以说大多数项目都采用了“git flow”。但只有少数项目真正需要这种策略。通常是因为这些项目是版本控制型软件。
/feature 分支策略
master
更容易管理,尤其是在你刚开始使用的时候。而且如果需要,切换到“git flow”也非常容易。 -
git open
您使用的命令是什么?它是一个单独的命令,可以作为npm 包使用。
-
当文件已添加到其他分支但在您的工作分支中仍显示为未跟踪或已修改时,如何重置分支?
这通常是由于“工作索引”不干净时切换分支的结果。
Git 没有内置的方法来解决这个问题。我通常会确保我的提示符有一个“状态”指示器,并在
git status
每次更改分支时运行命令来避免这种情况。这些习惯让我有机会尽早发现这一点,以便我可以在新的分支上进行这些更改
stash
。commit
-
我如何重命名分支?
git branch -m current-branch-name new-branch-name
-
我如何使用
cherry-pick
?git cherry-pick [reference]
。请记住,这是一个重新应用命令,因此它将更改提交 SHA。 -
如果我从某个分支恢复(例如
HEAD~3
),是否可以再次返回HEAD
(例如恢复上次更新)?在这种情况下,我会通过运行立即撤消
revert
提交(即提交) 。HEAD
git reset --hard HEAD~1
-
什么时候使用
git pull
和git fetch
?git pull
将会下载提交到当前分支。记住,实际上是和命令git pull
的组合。fetch
merge
git fetch
将从远程检索最新的引用。一个很好的类比是播客播放器或电子邮件客户端。您可能会检索最新的播客或电子邮件(获取),但实际上您尚未将播客或电子邮件附件下载到本地(拉取)。
-
为什么有时我们需要使用它
--force
来推动 rebase 的更改?rebase
是一个可能重新应用提交的命令,这会改变其 SHA1 哈希值。如果发生这种情况,本地提交历史记录将不再与其远程分支对齐。当这种情况发生时,您将被拒绝
push
。只有在被拒绝的情况下,您才应该考虑使用git push --force
。这样做会用本地提交历史记录覆盖远程提交历史记录。所以,请放慢速度,思考一下为什么你需要使用
--force
。 -
能否使用一个分支来合并多个分支,然后将这个分支发送到master?
当然。在大多数 Git 工作流程中,分支会积累来自多个其他分支的更改,这很常见。最终,这些分支会被“提升”到主分支。
-
我应该从一个非常旧的分支进行重新定基吗?
除非你必须这么做。
根据您的工作流程,可能可以将陈旧的分支合并到主分支中。
如果你需要更新某个分支,我更喜欢
rebase
。它提供了更清晰的历史记录,只包含你的更改,而不是来自其他分支或合并的提交。然而,虽然总是可行的,但使用
rebase
可能会是一个痛苦的过程,因为你的每次提交都会被重新应用。这可能会导致多次冲突。如果是这样,我通常会--abort
使用rebase
和merge
来一次性解决所有冲突。 -
使用时,和
rebase -i
有什么区别?squash
fixup
并
squash
结合fixup
两次提交。squash
暂停变基过程并允许您调整其提交消息。fixup
自动使用来自第一次提交的消息。 -
通常当我
rebase
使用我的功能分支时master
,对于每次提交我都需要解决冲突?是的。由于每次提交的更改都会在 期间重新应用
rebase
,因此您必须在发生任何冲突时立即解决它们。这意味着提交在流程早期就会发生冲突,或者如果您错误地解决了它,那么接下来的许多提交很可能也会发生冲突。
为了限制这种情况,我经常
rebase -i
首先压缩我的提交历史,以便于处理。如果许多提交之间仍然存在冲突,我可能会使用
merge
。 -
在将我的分支与 master 合并之前,是否有必要用 master 更新我的分支?
根据您的工作流程,可能可以将陈旧的分支合并到主分支中。
如果您的工作流程仅使用“快进”合并,则需要在合并之前更新您的分支。
-
您推荐使用 GitKraken 吗?
我提倡在命令行中使用 Git。我发现这能让我完全掌控变更管理,并使用命令来改进我的开发流程。
当然,某些可视化操作,例如管理分支和查看文件差异,在 GUI 中总是更好。我个人认为在合并过程中在浏览器中查看这些内容就足够了。
-
--amend
当它已经被推送时,你还能进行提交吗?是的。但是,您不会希望在合并到另一个分支后再修改提交,因为
--amend
提交会发生变化。 -
当我知道我将在某件事上工作一段时间时,我应该为每个更改打开一个拉取请求还是为所有工作打开一个完整的拉取请求?
您通常希望为所有工作打开一个拉取请求。
但是,如果你要长时间处理某件事,那么在过程中合并较小的更改可能会有所帮助。这样做可以防止对分支的依赖或过时。
这取决于您所做的更改类型。
-
release
在合并分支之前先创建一个分支是一种好的做法吗master
?这很大程度上取决于你的部署流程。创建
release
分支可以有效地将多个分支的工作集中在一起,并在合并到主分支之前进行整体测试。由于源分支保持独立且未合并,因此您在最终合并时将拥有更大的灵活性。
-
如何从中获取部分提交
master
?假设我不想获取最后一次提交,而是进行 rebase。假设
master
这是你的主分支,你肯定不想选择性地从它的历史记录中提取提交。这会导致后续冲突。您将希望
merge
或rebase
您的分支将拥有来自主分支的所有更改。要从主分支以外的分支中提取选定的提交,您可以使用
git cherry-pick
。 -
我可以在我的终端上设置一些特殊主题吗?
我在“获取 Git”中介绍了如何配置和自定义终端。
-
除了使用命令之外,哪个选项最好
git push --force
?确实没有其他选择
git push --force
。话虽如此,如果您使用
merge
或正确更新您的分支,则rebase
您不需要使用git push --force
。仅当您运行了更改您之前共享的历史记录的本地提交历史记录的命令时才需要
git push --force
。 -
当我
drop
在 期间选择时git rebase -
,与该提交相关的代码会被删除吗?是的!
要恢复此代码,您需要找到之前的
rebase
状态reflog
。 -
我们如何自动跟踪远程分支?
checkout
通常,当您创建分支时,Git 会自动设置分支跟踪。如果没有,您可以在下次推送时使用以下命令进行更新:
git push -u remote-name branch-name
。或者您可以使用以下方式明确设置它:
git branch --set-upstream-to=remote-name/branch-name
-
最佳实践
rebase
在更新之前是否是一个分支?我相信如此,原因很简单,
git rebase -i
首先组织或折叠您的提交会在更新过程中为您提供更多背景信息。 -
有没有办法将一个提交拆分为多个提交(与
fixup
/相反squash
)?您可以在过程
exec
中使用该命令rebase -i
尝试修改工作索引并拆分更改。您还可以使用
git reset
撤消最近的提交并将其更改放在工作索引中,然后将它们的更改分离到新的提交中。 -
有没有办法去查看已修复的提交?
不是之前的提交。您可以使用它
git show
来查看新提交中的更改吗? -
什么意思
rebase --skip
?这告诉
rebase
在变基过程中不要应用当前更改。 -
我如何删除远程分支?
您可以通过按下“nothing”来删除远程分支:
git push origin :branch-name-to-remove
或者使用-d
选项:git push -d origin some-other-branch-2
。要删除对远程分支的本地引用,您可以运行:
git remote prune origin
。 -
checkout
和有啥区别reset
?这两个命令都可用于撤消更改。
checkout
可以说更强大,因为它不仅允许您撤消当前更改,还可以通过检索文件的旧版本来撤消一组更改。reset
默认情况下,它更多地用于更改工作索引中的变更状态。因此,它实际上只处理当前的变更。我更喜欢
reset
。这种措辞更符合操作逻辑,通常是更改状态或放弃当前更改。我倾向于将其保留checkout
用于切换分支以及偶尔需要恢复文件旧版本的情况。 -
在正常的工作流程中我应该避免使用哪些命令?
任何可能破坏您的历史记录的内容,例如:
git push origin master -f
(绝不)git revert
(在功能分支上)git cherry-pick
(更改自master
)
在正常的工作流程下,我尽量避免
git merge
直接使用,因为这通常是通过拉取请求内置到流程中的。 -
如果我有一个分支 (B) 指向另一个分支 (A),并且我还有另一个分支 (C),它需要来自 (A) 和 (B) 以及主分支的代码,那么必须遵循哪个流程才能更新 (C)?
有意思。这取决于几个因素……
和可以合并吗?
A
如果可以,您可以将和合并到,然后使用 的最新更改进行更新。B
master
A
B
master
C
master
如果没有,您可能能够简单地
B
合并,C
因为它已经包含了更改A
。在极端情况下,您可以将
A
、B
和master
合并到中C
。但是,为了避免冲突,合并的顺序可能很重要。 -
您使用过哪些别名?
我很少给 Git 命令添加别名,尤其是核心命令。我发现这样做会造成混淆,尤其是作为一名培训师。
话虽如此,我确实有一些常用命令或带有许多选项的命令的别名:
alias.unstage reset HEAD -- alias.append commit --amend --no-edit alias.wip commit -m "WIP" alias.logo log --oneline alias.lola log --graph --oneline --decorate --all
-
有哪些鲜为人知的 Git 命令?
git bisect
它可以帮你轻松找到代码中现有的 bug。虽然我只用过几次,但它的精准度令人印象深刻,让我省去了在大海捞针的几个小时。git archive
是另一个打包一系列变更的好工具。这有助于与第三方共享工作或进行微部署。git reflog
可能是众所周知的,但值得一提,因为它提供了一种在出现问题时“撤消”命令的好方法。 -
您能推荐一些有关学习 Git 的书籍吗?
当然。我建议至少读完《Pro Git》的前三章。这些年来,我已经读过好几次了,每次都能学到一些东西。
当然,我毫不掩饰地推荐《Getting Git》。我的视频课程涵盖了从命令行使用所有 Git 命令的基本用法和高级用法。
-
如果我还有更多的问题怎么办?
太棒了。通过 Twitter 发给我吧。
*摄影:Bob Jansen
文章来源:https://dev.to/gonedark/42-git-questions-answered-3npa