git 将文件提交到不同的分支而无需签出
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7933044/
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
Commit a file to a Different Branch Without Checkout
提问by Schneems
Is it possible to commit a file in a git branch with out checking out that branch? If so how?
是否可以在 git 分支中提交文件而不检查该分支?如果是这样怎么办?
Essentially I want to be able to save a file in my github pages branch without switching branches all the time. Any thoughts?
本质上,我希望能够在我的 github pages 分支中保存文件,而无需一直切换分支。有什么想法吗?
Update:It's not possible to do what I want (see comments below for use case). What I ended up doing is programmatically cloning my current directory to a tmp directory, then checking out my branch in that tmp directory (doesn't affect my working directory) and committing my files to the tmp directory clone. When I'm done, I push back to my working directory and delete the tmp directory. Sucks, but it's the only way to commit files to another branch without changing the current working branch of the working directory. If anyone has a better solution, please feel free to add it below. If it's better than 'it cannot be done', I'll accept yours.
更新:不可能做我想做的事(有关用例,请参阅下面的评论)。我最终做的是以编程方式将我的当前目录克隆到 tmp 目录,然后在该 tmp 目录中检出我的分支(不影响我的工作目录)并将我的文件提交到 tmp 目录克隆。完成后,我推回我的工作目录并删除 tmp 目录。糟糕,但这是在不更改工作目录的当前工作分支的情况下将文件提交到另一个分支的唯一方法。如果有人有更好的解决方案,请随时在下面添加。如果它比“无法完成”更好,我会接受你的。
采纳答案by CharlesB
It's not possible.
这是不可能的。
The changes you commit are related to the current working copy. If you want to commit to another branch it means that you could commit changes from your working copy, but base them from another copy state.
您提交的更改与当前工作副本相关。如果你想提交到另一个分支,这意味着你可以从你的工作副本提交更改,但是它们基于另一个副本状态。
This is not a natural way of versioning your work, and this is why you need to make different steps (stash changes, checkout the branch, pop stash and commit) to accomplish it.
这不是对您的工作进行版本控制的自然方式,这就是为什么您需要执行不同的步骤(存储更改、签出分支、弹出存储和提交)来完成它。
As for your specific use case, a simple way is to keep two copies of your work, one checked out at master
branch, and the other at pages
branch.
至于您的特定用例,一个简单的方法是保留您的工作的两份副本,一份在master
分支检出,另一个在pages
分支。
In the pages
working copy, add the master
copy as a remote repo.
在pages
工作副本中,将副本添加master
为远程存储库。
- You commit pages on
master
- Pull from
master
on thepages
copy - push to GitHub
- reset the master branch at its previous state.
- 你提交页面
master
- 从副本
master
上拉pages
- 推送到 GitHub
- 将 master 分支重置为其先前的状态。
回答by p'tit fred
It can be done by reimplementing git commit.
它可以通过重新实现 git commit 来完成。
This can be done with various call to git hash-object
这可以通过各种调用来完成 git hash-object
But this is hard to achieve.
但这很难实现。
Please read progit chapter 9for more details and a full example of how to simulate a commit.
请阅读progit 第 9 章以获取更多详细信息以及如何模拟提交的完整示例。
回答by CB Bailey
So long as you don't have anything in your current index that differs from your HEAD
that you want to keep you can so something like this. (If you do want to keep your index you could temporarily export the GIT_INDEX_FILE
environment variable to point at a temporary file for the duration of these commands.)
只要您当前的索引中没有与HEAD
您想要保留的不同的任何内容,您就可以这样做。(如果您确实想保留索引,您可以GIT_INDEX_FILE
在这些命令的持续时间内临时导出环境变量以指向临时文件。)
# Reset index and HEAD to otherbranch
git reset otherbranch
# make commit for otherbranch
git add file-to-commit
git commit "edited file"
# force recreate otherbranch to here
git branch -f otherbranch
# Go back to where we were before
# (two commits ago, the reset and the commit)
git reset HEAD@{2}
We've never actually checked out otherbranch
and our working tree files haven't been touched.
我们从来没有真正签出过otherbranch
,我们的工作树文件也没有被触及。
回答by torek
As several others have said, it is literally possible, but impractical.
正如其他几个人所说,这确实是可能的,但不切实际。
However, as of Git 2.5 (with some important fixes in 2.6 and minor ones since then), there isa practical method for doing this using git worktree add
.
但是,从 Git 2.5 开始(在 2.6 中进行了一些重要的修复,然后是次要修复),有 一种实用的方法可以使用git worktree add
.
Let's say, for instance, that you want to work on branches main
and doc
"at the same time", or branches develop
and test
"at the same time", but the two branches in question deliberately contain different things. (For instance, the doc
branch has documentation that exists outside or alongside the code, or the test
branch has tests that will be run against the code, but not distributed, or which are expected to have failures for which tests are deliberately skipped on the develop
side, or whatever.)
比方说,比如,要在分支机构的工作main
,并doc
“在同一时间”,或分支机构develop
和test
“在同一时间”,但问题的两个分支故意含有不同的东西。(例如,doc
分支具有存在于代码外部或旁边的文档,或者test
分支具有将针对代码运行但未分发的测试,或者预期会出现故障而故意跳过测试的测试develop
,管他呢。)
Instead of just:
而不仅仅是:
git clone -b develop <source> theclone
followed by working in theclone
with constant switching back and forth between the two branches, you would:
然后theclone
在两个分支之间不断来回切换,您将:
git clone -b develop <source> theclone
but then:
但是之后:
cd theclone
git worktree add ../ct test # check out branch test in ../ct
or just:
要不就:
git worktree add ../test # check out branch test in ../test
Now you can run your tests in ../test
while developing in theclone
. You can merge and/or rebase changes from one branch to the other in the usual way: the underlying repository is already shared, so no git push
or git fetch
is required. You simply have bothbranches checked out, into two separate work-trees, named theclone
and test
from the top level.
现在,您可以../test
在theclone
. 您可以以通常的方式将更改从一个分支合并和/或重新设置为另一个分支:底层存储库已经共享,因此不需要git push
或git fetch
不需要。您只需将两个分支都检出到两个独立的工作树中,命名theclone
并test
从顶层开始。
回答by test30
I cannot agree it is not possible. By mixing git stash push
, git stash pop
, git checkout
, git checkout
, git add
and git commit
this is possible.
我不能同意这是不可能的。通过混合git stash push
,git stash pop
,git checkout
,git checkout
,git add
和git commit
这是可能的。
How I understand problem:
我如何理解问题:
You are on branch master and you made some modifications to file patched.txt
and you would like to commit this file to other branch.
您在 master 分支上并且对文件进行了一些修改,patched.txt
并且您想将此文件提交到其他分支。
What you would like to do is:
你想做的是:
- save all changes in this repo by doing git stash
- checkout
file.txt
from stashed stack - add file
patched
(and only this file) to new branch - get back to state of repo before modyfing
file.txt
- 通过执行 git stash 保存此 repo 中的所有更改
file.txt
从隐藏的堆栈中结帐- 将文件
patched
(仅此文件)添加到新分支 - 在修改之前回到回购状态
file.txt
This can be achieved by executing following commands:
这可以通过执行以下命令来实现:
destBranch=patch
thisBranch=master
FileToPutToOtherBranch="file1.txt file2.txt 'file with space in name.txt'"
message="patched files $FileToPutToOtherBranch"
#assumption: we are on master to which modifications to file.txt should not belong
git stash &&\ #at this point we have clean repository to $thisBranch
git checkout -b $destBranch &&\
git checkout stash@{0} -- $FileToPutToOtherBranch && #if there are many files, repeat this step #create branch if does not exist (param -b)
git add $FileToPutToOtherBranch &&\ # at this point this is equal to git add . --update
git commit -m "$message" &&\
git checkout $thisBranch &&\
git stash apply &&\ # or pop if want to loose backup
git checkout $thisBranch -- $FileToPutToOtherBranch # get unpatched files from previous branch
The reason why I am using "&&" and the end is if somebody will copy&paste this snippet into terminal, even if one error occurs, next commands will be executed, which is not good. \ is for informing shell that command is continued in next line.
我之所以使用“&&”,最后的原因是如果有人将这个片段复制并粘贴到终端中,即使发生了一个错误,也会执行下一个命令,这并不好。\ 用于通知 shell 命令在下一行继续。
To proove this works I provide testing environment for this snippet
为了证明这是有效的,我为此片段提供了测试环境
mkdir -p /tmp/gitcommitToAnyBranch && cd /tmp/gitcommitToAnyBranch &&\
git init
echo 'this is master file' > file1.txt
echo 'this is file we do not want to have modified in patch branch because it does not patches any feature' > docs.txt
git add file1.txt && git commit -m "initial commit"
echo 'now this file gets patched' > file1.txt
git status
Now, if you run my script with parameters
现在,如果您使用参数运行我的脚本
destBranch=patch
thisBranch=`git rev-parse --abbrev-ref HEAD`
FileToPutToOtherBranch="file1.txt"
message="patched file $FileToPutToOtherBranch"
You will have file1.txt
modified only in patch branch, for more see gitk --all
您将file1.txt
仅在补丁分支中进行修改,有关更多信息,请参见gitk --all
回答by qwertzguy
I made a little tool that does exactly this: https://github.com/qwertzguy/git-quick
我做了一个小工具,完全可以做到这一点:https: //github.com/qwertzguy/git-quick
It let's you edit specific files from another branch without checking out the other branch completely (just the files you want to edit) and commit them. All this without ever affecting your working copy or staging area.
它让您可以从另一个分支编辑特定文件,而无需完全检出另一个分支(只是您要编辑的文件)并提交它们。所有这一切都不会影响您的工作副本或暂存区。
Behind the scenes it uses a combination of git worktree and sparse checkout. The source is fairly small, so you can read through.
在幕后,它使用了 git worktree 和稀疏结帐的组合。来源相当小,所以你可以通读。
回答by codingFoo
While there is currently no single command to do this, there are at least two other options.
虽然目前没有单一的命令可以做到这一点,但至少还有其他两个选项。
You could use the github api to create the commit. This postdetails creating a commit in a github repo.
Use a series of plumbing commands to create the commit.
The git book has a descriptionof plumbing commands used to create a commit
note: the command is now mktree not mk-tree
注意:命令现在是 mktree 而不是 mk-tree
回答by Arteymix
If you accidently modified things in the wrong branch, here's some simple steps :
如果您不小心修改了错误分支中的内容,这里有一些简单的步骤:
- Commit these changes ;
- Merge them into the right branch ;
- Checkout the branch your were on at first and reset it to the commit before ;
- Cleanup your modifications with "git checkout -- .".
- 提交这些更改;
- 将它们合并到正确的分支中;
- 首先检查您所在的分支并将其重置为之前的提交;
- 用“git checkout -- .”清理你的修改。
Everything should be fine after this. You can also merge, reset and cleanup your modifications selectively.
在这之后一切都应该没问题。您还可以有选择地合并、重置和清理您的修改。
回答by leandro souza rosa
No you cannot, however what you are doing by hard copying files is implemented by git stash
using commits. The stash
works as a stack of changes that are saved "somewhere outside the branches spaces", hence can be used to move modifications between branches.
不,你不能,但是你通过硬拷贝文件所做的事情是通过git stash
使用提交来实现的。该stash
作品作为保存在“分支空间之外的某处”的一堆更改,因此可用于在分支之间移动修改。
- Make your changes on
<file>
- git add
<file>
- git stash
- git checkout
<branch you want to commit>
- git stash pop
- git commit -m "
<commit message>
"
- 进行更改
<file>
- 添加
<file>
- 混帐
- 结帐
<branch you want to commit>
- git stash pop
- git commit -m "
<commit message>
"
you can probably scrip these simple commands down if you do this constantly.
如果你经常这样做,你可能可以把这些简单的命令写下来。
回答by jordan314
This is how I do it:
这就是我的做法:
if I've acidentally committed, roll back one commit:
如果我已经认真地提交了,请回滚一次提交:
git reset --soft 'HEAD^'
add the files you want to add
添加要添加的文件
git add .
create a new temporary branch:
创建一个新的临时分支:
git checkout -b oops-temp
commit your changes:
提交您的更改:
git commit -m "message about this commit"
checkout the branch you meant to check out:
结帐您打算结帐的分支:
git checkout realbranch
merge the old branch:
合并旧分支:
git merge oops-temp
delete the old branch:
删除旧分支:
git branch -D oops-temp