在没有文件签出的情况下切换 Git 分支
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1282639/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Switch Git branch without files checkout
提问by tig
Is it possible in Git to switch to another branch without checking out all files?
在 Git 中是否可以在不检查所有文件的情况下切换到另一个分支?
After switching branch I need to delete all files, regenerate them, commit and switch back. So checking out files is just a waste of time (and there are about 14,000 files - it is a long operation).
切换分支后,我需要删除所有文件,重新生成它们,提交并切换回来。所以检查文件只是浪费时间(大约有 14,000 个文件 - 这是一个很长的操作)。
To make everything clear:
为了让一切都清楚:
I need all this to upload documentationto GitHub.
我需要所有这些才能将文档上传到 GitHub。
I have a repository with the gh-pagesbranch. When I rebuild documentation locally, I copy it to the repository directory, commit and push to GitHub. But I was not happy, because I had two copies of documentation locally. And I decided to create an empty branch and after committing, switch to empty and delete files. But switching back is a long operation - so I asked this question.
我有一个带有gh-pages分支的存储库。当我在本地重建文档时,我将其复制到存储库目录,提交并推送到 GitHub。但是我并不高兴,因为我在本地有两份文档。我决定创建一个空分支,提交后,切换到空并删除文件。但是切换回来是一个漫长的操作——所以我问了这个问题。
I know that I can just leave on the gh-pagesbranch and delete files, but I don't like dirty working trees.
我知道我可以离开gh-pages分支并删除文件,但我不喜欢肮脏的工作树。
回答by CB Bailey
Yes, you can do this.
是的,你可以这样做。
git symbolic-ref HEAD refs/heads/otherbranch
If you need to commit on this branch, you'll want to reset the index too otherwise you'll end up committing something based on the last checked out branch.
如果你需要在这个分支上提交,你也需要重置索引,否则你最终会根据最后一个签出的分支提交一些东西。
git reset
回答by tig
Using basic git commands only:
仅使用基本的 git 命令:
This answer is a bit longer than that of Charles, but it consists solely of basic git commands that I can understand and thus remember, eliminating the need to keep looking it up.
这个答案比 Charles 的要长一点,但它只包含我能理解并记住的基本 git 命令,无需继续查找。
Mark your current location (commit first if needed):
标记您的当前位置(如果需要,请先提交):
git checkout -b temp
Reset (moves) the marker to the other branch without changing working dir:
将标记重置(移动)到另一个分支而不改变工作目录:
git reset <branch where you want to go>
now temp and other branch point to the same commit, and your working dir is untouched.
现在 temp 和其他分支指向同一个提交,并且您的工作目录未受影响。
git checkout <branch where you want to go>
since your HEAD is already pointing to the same commit, working dir is not touched
由于您的 HEAD 已经指向同一个提交,因此不会触及工作目录
git branch -d temp
Note that these commands are also readily available from any graphical client.
请注意,这些命令也可以从任何图形客户端轻松获得。
回答by Tino
In v2.24
git switch
is something like a safegit checkout
.
Hence I renamed the alias below togit hop
for
"hop on the branch without changing worktree"
在 v2.24
git switch
中类似于一个安全的git checkout
.
因此,我将下面的别名重命名git hop
为
“在不更改工作树的情况下跳上分支”
For the benefit of the reader:
为了读者的利益:
While I think that Charles Bailey's solutionis a correct one, this solution needs a tweak when switching to something, which is not a local branch. Also there should be some way how to do it with regular commands which is easy to understand. Here is what I came up with:
虽然我认为Charles Bailey 的解决方案是正确的,但该解决方案在切换到某个非本地分支时需要进行调整。也应该有一些方法如何使用易于理解的常规命令来做到这一点。这是我想出的:
git checkout --detach
git reset --soft commitish
git checkout commitish
Explained:
解释:
git checkout --detach
is the same asgit checkout HEAD^{}
which leaves the current branch behind and goes into "detached head state". So the next modification ofHEAD
no more affects any branch. DetachingHEAD
does not affect the worktree nor the index.git reset --soft commitish
then movesHEAD
to the SHA of the givencommitish
. If you want to update the index, too, leave--soft
away, but I do not recommend to do so. This, again, does not touch the worktree, and (--soft
) not the index.git checkout commitish
then attachesHEAD
to the givencommitish
(branch) again. (Ifcommitish
is a SHA nothing happens.) This, too, does not affect index nor worktree.
git checkout --detach
与git checkout HEAD^{}
将当前分支留在后面并进入“分离头状态”相同。所以下一次修改HEAD
no more 会影响任何分支。分离HEAD
不会影响工作树和索引。git reset --soft commitish
然后移动HEAD
到给定的 SHAcommitish
。如果您也想更新索引,请--soft
离开,但我不建议这样做。同样,这不会触及工作树,并且 (--soft
) 不会触及索引。git checkout commitish
然后再次附加HEAD
到给定的commitish
(分支)。(如果commitish
是 SHA,则什么也不会发生。)这也不会影响索引或工作树。
This solution accepts everything which refers to a commit, so this is ideal for some git
alias. The rev-parse
below is just a test to make sure, nothing breaks in the chain, such that typos do not accidentally switch into detached head state (error recovery would be way more complex).
此解决方案接受所有涉及提交的内容,因此这是某些git
别名的理想选择。在rev-parse
下面仅仅是一个测试,以确保在链没有断裂,使得错别字不小心切换到分离的头的状态(错误恢复将是方式更复杂)。
This leads to following git hop treeish
alias:
这导致以下git hop treeish
别名:
git config --global alias.hop '!f() { git rev-parse --verify "$*" && git checkout "HEAD^{}" && git reset --soft "$*" && git checkout "$*"; }; f'
FYI, you can find it in my list of git
aliases.
仅供参考,您可以在我的git
别名列表中找到它。
回答by Jakub Nar?bski
Wouldn't be a better solution to have two working directories (two working areas) with one repository, or even two repositories?
将两个工作目录(两个工作区)与一个存储库或什至两个存储库一起使用不是更好的解决方案吗?
There is git-new-workdirtool in contrib/
section to help you with this.
部分中有git-new-workdir工具contrib/
可以帮助您解决这个问题。
回答by Greg Hewgill
I think you're looking for the plumbing command git read-tree
. This will update the index but will not update any files in your working directory. For example, assuming branch
is the name of the branch to read:
我认为您正在寻找管道命令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
回答by user157005
You can overwrite your HEAD file with a different branch name:
您可以使用不同的分支名称覆盖您的 HEAD 文件:
echo "ref: refs/heads/MyOtherBranch" > .git/HEAD
echo "ref: refs/heads/MyOtherBranch" > .git/HEAD
回答by Norman Ramsey
With so many files, you may be best off just keeping two repos, one for each branch. You can pull changes back and forth as needed. This is going to be less surprising than trying to play scurvy tricks with git.
有这么多文件,最好只保留两个存储库,每个分支一个。您可以根据需要来回拉动更改。这不会比尝试用 git 玩坏血病的把戏更令人惊讶。
回答by Tim Abell
If you are simply trying to change where a remote branch points, you can do it with "git push" without touching your local copy.
如果您只是想更改远程分支指向的位置,则可以使用“git push”来完成,而无需触及您的本地副本。
http://kernel.org/pub/software/scm/git/docs/git-push.html
http://kernel.org/pub/software/scm/git/docs/git-push.html
The format of a <refspec> parameter is an optional plus +, followed by the source ref <src>, followed by a colon :, followed by the destination ref <dst>. It is used to specify with what <src> object the <dst> ref in the remote repository is to be updated.
<refspec> 参数的格式是一个可选的加号 +,后跟源引用 <src>,后跟冒号 :,后跟目标引用 <dst>。它用于指定要更新远程存储库中的 <dst> 引用的 <src> 对象。
eg, to update foo to commit c5f7eba do the following:
例如,要更新 foo 以提交 c5f7eba,请执行以下操作:
git push origin c5f7eba:foo
Not sure if that's what you were after or not.
不确定这是否是您所追求的。
回答by Haseena Parkar
you can make use of
你可以利用
1. git checkout -f <new-branch>
2. git cherry-pick -x <previous-branch-commit-id>
previous-branch-commit-id is the commit from where you want to copy old the data.
previous-branch-commit-id 是您想要复制旧数据的提交。