在 Git 中是否可以在不检查所有文件的情况下切换到另一个分支?
切换分支后,我需要删除所有文件,重新生成它们,提交并切换回来。所以签出文件只是浪费时间(大约有 14,000 个文件 - 这是一个很长的操作)。
为了让一切都清楚:
我需要所有这些才能将 documentation 上传到 GitHub。
我有一个带有 gh-pages 分支的存储库。当我在本地重建文档时,我将其复制到存储库目录,提交并推送到 GitHub。但我并不高兴,因为我在本地有两份文档副本。我决定创建一个空分支,提交后,切换到空并删除文件。但是切换回来是一个漫长的操作——所以我问了这个问题。
我知道我可以留在 gh-pages 分支上并删除文件,但我不喜欢肮脏的工作树。
是的,你可以这样做。
git symbolic-ref HEAD refs/heads/otherbranch
如果你需要在这个分支上提交,你也需要重置索引,否则你最终会根据最后签出的分支提交一些东西。
git reset
仅使用基本的 git 命令:
这个答案比查尔斯的答案要长一点,但它只包含我能理解并因此记住的基本 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
请注意,这些命令也可以从任何图形客户端轻松获得。
git reset --soft <branch where you want to go>
避免更新索引
在 v2.24 中,git switch 类似于安全的 git checkout。因此,我将下面的别名重命名为 git hop 以表示“在分支上跳而不更改工作树”
为了读者的利益:
虽然我认为 Charles Bailey's solution 是正确的,但此解决方案在切换到某个不是本地分支的东西时需要进行调整。还应该有一些方法可以使用易于理解的常规命令来做到这一点。这是我想出的:
git checkout --detach
git reset --soft commitish
git checkout commitish
解释:
git checkout --detach 与 git checkout HEAD^{} 相同,它将当前分支留在后面并进入“分离头状态”。所以 HEAD 的下一次修改不再影响任何分支。分离 HEAD 不会影响工作树和索引。
git reset --soft commitish 然后将 HEAD 移动到给定 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
aliases 列表中找到它。
$@
而不是 $*
吗?不同之处在于 $@ 没有扩展带引号的参数,其中有空格。
$@
绝对不是这里的意思。使用 $*
代替 $1
,使得 git switch -f b
与 git switch '-f b'
相同,这应该是一个错误。这样我就可以通过省略一些错误处理来缩短别名,例如 !f() { [ 1 = $# ] || { echo 'WTF!'; return 1; }; ..
拥有两个工作目录(两个工作区域)和一个存储库,甚至两个存储库不是更好的解决方案吗?
contrib/
部分中有 git-new-workdir 工具可帮助您解决此问题。
git-new-worktree
脚本早于 git worktree
子命令;编写答案时,此命令不可用。例如,该脚本需要符号链接支持;恕我直言,最好使用本机支持。
我认为您正在寻找管道命令 git read-tree
。这将更新索引,但不会更新工作目录中的任何文件。例如,假设 branch
是要读取的分支的名称:
git read-tree branch
如果你想提交到你刚刚阅读的分支,你还需要:
git symbolic-ref HEAD refs/heads/branch
read-tree
生成错误:fatal: Not a valid object name branch
如果还没有任何 git switch branch
branch
替换为您的目标分支名称。
您可以使用不同的分支名称覆盖您的 HEAD 文件:
echo "ref: refs/heads/MyOtherBranch" > .git/HEAD
git symbolic-ref HEAD refs/heads/MyOtherBranch
kernel.org/pub/software/scm/git/docs/git-symbolic-ref.html
git symbolic-ref
做到这一点吗?
或者只是使用补丁文件从您的另一个分支修补到您的主分支
git diff otherbranch master > ~/tmp/otherbranch.diff
git checkout master
git apply ~/tmp/otherbranch.diff
有这么多文件,最好只保留两个存储库,每个分支一个。您可以根据需要来回拉取更改。这不会比试图用 git 玩坏血病的把戏更令人惊讶。
git-new-worktree
代替(在 contrib/
中)
如果您只是尝试更改远程分支指向的位置,则可以使用“git push”来完成,而无需触及本地副本。
http://kernel.org/pub/software/scm/git/docs/git-push.html
例如,要更新 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 的当前提交 ref,例如“99ce9a2”,
git checkout A
git reset --hard B
git reset 99ce9a2
您现在应该在分支 A 上,其文件夹结构对应于 B,显示为未暂存的更改(A 历史记录未更改)。
不定期副业成功案例分享
echo "ebff34ffb665de0694872dceabe0edeaf50ec5a9" > .git/HEAD
后跟git reset
来指向 ref 而不是分支。git update-ref HEAD refs/heads/otherbranch
git stash
2.git checkout -b otherBranch
3.git stash pop
git update-ref
很有用,但它也会移动当前分支的尖端。git reset refs/heads/otherbranch
来获得相同的结果