这两个问题的答案是“不完全”和“否”,但也有“通常没有必要”,而事实上,问题本身并没有多大意义。第一个也是最大的问题在于“如果本地是干净的”这句话——这究竟是什么意思?
如果“干净”是指git status 报告的内容:
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree clean
那么“干净”指的是工作树,有时可能指的是索引,与彼此和/或HEAD提交相比。
除非您使用git worktree add 创建辅助工作树,否则任何给定的 Git 存储库都只有 一个 工作树(和一个相应的索引)。 (如果您确实使用git worktree add,每个添加的工作树都在其自己的单独分支上。这实际上可能是您真正想要的答案,在这里。)
我们还要注意,像master 或feature 这样的分支name 表示一个特定的提交,Git 将其称为该分支的tip 提交。 “分支”一词还有其他含义:参见What exactly do we mean by "branch"? 但是当您签出一个分支时,这意味着您也签出了一个特定的commit。该提交的内容填充索引和工作树。
切换分支或“分离的 HEAD”的命令是 git checkout。它通过写入索引和工作树来完成分支切换(或 HEAD 分离),以实现从之前签出的提交到您将签出的提交的切换现在。如果工作树在git checkout之前是干净的,这总是可能的,并且工作树在git checkout 之后之后也是干净的。 p>
如果工作树在git checkout 之前不干净,则有时(但并非总是)仍然可以切换分支:请参阅Checkout another branch when there are uncommitted changes on the current branch。在这种情况下,工作树通常也会在git checkout 切换分支之后不干净。不干净是因为签出在切换分支时不必更新与您在运行git checkout <em>branchname</em> 之前签出的提交不匹配的文件的索引和工作树条目。
检查工作树是否干净
除了上面的内容,请注意 git-sh-setup,一个可用于其他 Git 脚本的脚本,包括 a function named require_clean_work_tree。您可以检查此代码,或者直接使用它来确定工作树是否干净。
您可以将它与phd's answer about using a post-checkout hook 结合起来进行检查,如果合适,运行git merge 或git fetch && git merge。 (我建议完全避免git pull:像这样把它分解成两个独立的步骤。之后你的生活会更快乐。)
为什么我怀疑你根本不需要这个
(我们的分支经常被创建和删除,因为公司政策是每个任务一个分支,在审查时被 PR 和合并)
作为一般规则,如果您不打算在命名分支上工作(在其上进行新提交),则不应首先创建它。没有创建它,您也不必担心更新它。
例如,假设您有一个存储库,其中有一个名为origin 的远程服务器,并且在origin 上,有用于各种任务的分支。您想偶尔检查 origin/task/feedkittens,但处理(单个)任务task/fillcatnip。
在这种情况下,要检查事物,请继续使用“分离 HEAD”模式:
git checkout origin/task/feedkittens
要处理事情,请使用git checkout 来创建 task/fillcatnip 来自 origin/task/fillcatnip:
git checkout task/fillcatnip
这是因为git checkout 会在您要求它检查一个不存在 的分支时,搜索另一个名称相同的origin/ 分支。如果是这样,它将创建本地分支,使得分支提示提交与远程跟踪名称的提交相同。同时,它会将本地分支设置为track(将其作为上游)远程跟踪名称。
通过创建本地分支名称,您现在可以创建新提交。这些将使本地分支
通过避免创建task/feedkittens,您只需运行git fetch 和git checkout origin/task/feedkittens 即可查看最新信息。您将处于“分离 HEAD”模式,因此现在创建 new 提交通常不是一个好主意,但这意味着无需在本地分支周围拖动。
当在origin 上删除名为task/feedkittens 的分支时,您可以通过设置在git fetch 期间自动删除您自己的远程跟踪名称:
git config fetch.prune true
只要您git checkout 某个其他提交或名称,您就不会在不再有名称的origin/task/feedkittens 提交上被分离-HEAD。
如果您想同时处理(如“添加提交”)多个不同的分支,请考虑使用git worktree add,只要您的 Git 版本至少为 2.5。每个添加的工作树都有自己的私有索引,但所有添加的工作树共享单个底层存储库。如果您的 Git 太旧,请考虑为您要同时处理的每个分支制作单独的克隆。