切换不带文件签出的 Git 分支

在 Git 中有没有可能在不签出所有文件的情况下切换到另一个分支?

切换分支后,我需要删除所有文件,重新生成它们,提交和切换回来。因此,签出文件只是浪费时间(而且大约有14,000个文件——这是一个很长的操作)。

把话说清楚:

我需要这些来上传 文件到 GitHub。

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

我知道我可以留在 Gh-Pages分支上并删除文件,但我不喜欢肮脏的工作树。

61959 次浏览

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

回显“ ref: refs/HEAD/MyOtherBranch”> . git/HEAD

是的,你能做到。

git symbolic-ref HEAD refs/heads/otherbranch

如果您需要在这个分支上提交,那么您也需要重置索引,否则您将最终提交基于上一个签出分支的内容。

git reset

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

git read-tree branch

If you want to then commit to the branch you just read, you will also need to:

git symbolic-ref HEAD refs/heads/branch

有这么多的文件,你可能最好只保持两个回购,每个分支一个。您可以根据需要来回拉动更改。这不会比试图用 Git 玩卑鄙的把戏更令人惊讶。

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

contrib/部分有一个 Git-new-workdir工具可以帮助你。

如果您只是试图更改远程分支所指向的位置,那么您可以使用“ git push”来实现这一点,而不需要接触本地副本。

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

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

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

git push origin c5f7eba:foo

不知道这是不是你想要的。

仅使用基本的 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

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

你可以利用

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

Before-Branch-commit-id 是要从其中复制旧数据的提交。

在 v2.24中,git switch类似于一个安全的 git checkout
因此,我将下面的别名重命名为 git hop
“跳上树枝而不改变工作树”

为了读者的利益:

虽然我认为 查尔斯 · 贝利的解决方案是正确的,但是这个解决方案在切换到某个不是本地分支的东西时需要进行调整。还应该有一些方法,如何做到这一点与常规命令,这是很容易理解。以下是我的想法:

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

解释:

  • git checkout --detachgit checkout HEAD^{}相同,后者将当前的分支留在后面,进入“分离头状态”。因此 HEAD的下一次修改不再影响任何分支。分离 HEAD不会影响工作树和索引。
  • 然后,git reset --soft commitishHEAD移动到给定 commitish的 SHA。如果你也想更新索引,把 --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化名列表中找到它。

说你想去 A 分部,但是带着 B 分部的文件

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

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

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

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

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