繁体   English   中英

在没有文件签出的情况下切换 Git 分支

[英]Switch Git branch without files checkout

在 Git 中是否可以在不检查所有文件的情况下切换到另一个分支?

切换分支后,我需要删除所有文件,重新生成它们,提交并切换回来。 所以检查文件只是浪费时间(大约有 14,000 个文件 - 这是一个很长的操作)。

为了让一切都清楚:

我需要所有这些才能将文档上传到 GitHub。

我有一个带有gh-pages分支的存储库。 当我在本地重建文档时,我将其复制到存储库目录,提交并推送到 GitHub。 但是我并不高兴,因为我在本地有两份文档。 我决定创建一个空分支,提交后,切换到空并删除文件。 但是切换回来是一个漫长的操作——所以我问了这个问题。

我知道我可以离开gh-pages分支并删除文件,但我不喜欢肮脏的工作树。

是的,你可以这样做。

git symbolic-ref HEAD refs/heads/otherbranch

如果你需要在这个分支上提交,你也需要重置索引,否则你最终会根据最后一个签出的分支提交一些东西。

git reset

仅使用基本的 git 命令:

这个答案比 Charles 的要长一点,但它只包含我能理解并记住的基本 git 命令,无需继续查找。

标记您的当前位置(如果需要,请先提交):

git checkout -b temp

将标记重置(移动)到另一个分支而不改变工作目录:

git reset <branch where you want to go>

现在 temp 和其他分支指向同一个提交,并且您的工作目录未受影响。

git checkout <branch where you want to go>

由于您的 HEAD 已经指向同一个提交,因此不会触及工作目录

git branch -d temp

请注意,这些命令也可以从任何图形客户端轻松获得。

在 v2.24 中git switch就像一个安全的git checkout
因此我将下面的别名重命名为git hop for
“在不改变工作树的情况下跳上分支”

为了读者的利益:

虽然我认为Charles Bailey 的解决方案是正确的,但该解决方案在切换到某个非本地分支时需要进行调整。 也应该有一些方法如何使用易于理解的常规命令来做到这一点。 这是我想出的:

git checkout --detach
git reset --soft commitish
git checkout commitish

解释:

  • git checkout --detachgit checkout HEAD^{}相同,它将当前分支留在后面并进入“分离的头部状态”。 所以HEAD的下一次修改不再影响任何分支。 分离HEAD不会影响工作树和索引。
  • git reset --soft commitish然后将HEAD移动到给定commitish的 SHA。 如果您也想更新索引,请离开--soft ,但我不建议这样做。 同样,这不会触及工作树,并且( --soft )不会--soft索引。
  • git checkout commitish然后再次将HEAD附加到给定的commitish (分支)。 (如果commitish是 SHA,则什么也不会发生。)这也不会影响索引或工作树。

此解决方案接受所有涉及提交的内容,因此这是某些git别名的理想选择。 下面的rev-parse只是一个测试,以确保链中没有任何中断,这样拼写错误不会意​​外切换到分离的头部状态(错误恢复会更复杂)。

这导致以下git hop treeish别名:

git config --global alias.hop '!f() { git rev-parse --verify "$*" && git checkout "HEAD^{}" && git reset --soft "$*" && git checkout "$*"; }; f'

仅供参考,您可以在我的git aliases列表中找到它。

将两个工作目录(两个工作区域)与一个存储库甚至两个存储库一起使用不是更好的解决方案吗?

contrib/部分有git-new-workdir工具可以帮助你解决这个问题。

我认为您正在寻找管道命令git read-tree 这将更新索引但不会更新您工作目录中的任何文件。 例如,假设branch是要读取的分支的名称:

git read-tree branch

如果您想提交到您刚刚阅读的分支,您还需要:

git symbolic-ref HEAD refs/heads/branch

您可以使用不同的分支名称覆盖 HEAD 文件:

echo "ref: refs/heads/MyOtherBranch" > .git/HEAD

或者只是使用补丁文件从您的其他分支修补到您的主分支

git diff otherbranch master > ~/tmp/otherbranch.diff
git checkout master
git apply ~/tmp/otherbranch.diff

有这么多文件,最好只保留两个存储库,每个分支一个。 您可以根据需要来回拉动更改。 这不会比尝试用 git 玩坏血病的把戏更令人惊讶。

如果您只是想更改远程分支指向的位置,则可以使用“git push”来完成,而无需触及您的本地副本。

http://kernel.org/pub/software/scm/git/docs/git-push.html

<refspec> 参数的格式是一个可选的加号 +,后跟源引用 <src>,后跟冒号 :,后跟目标引用 <dst>。 它用于指定要更新远程存储库中的 <dst> 引用的 <src> 对象。

例如,要更新 foo 以提交 c5f7eba,请执行以下操作:

git push origin c5f7eba:foo

不确定这是否是您所追求的。

你可以利用

      1. git checkout -f <new-branch>
      2. git cherry-pick -x <previous-branch-commit-id>

previous-branch-commit-id 是您想要复制旧数据的提交。

假设您想在分支 A 中,但是要使用分支 B 中的文件

使用 git log 查找分支 A 的当前提交引用,例如“99ce9a2”,

git checkout A
git reset --hard B
git reset 99ce9a2

您现在应该位于分支 A 上,其文件夹结构对应于 B,显示为未暂存的更改(A 历史记录未更改)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM