如何 git-cherry-pick 只更改某些文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5717026/
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
How to git-cherry-pick only changes to certain files?
提问by Tobias Kienzler
If I want to merge into a Git branch the changes made only to some of the files changed in a particular commit which includes changes to multiple files, how can this be achieved?
如果我想将仅对特定提交中更改的某些文件所做的更改合并到 Git 分支中,其中包括对多个文件的更改,如何实现?
Suppose the Git commit called stuff
has changes to files A
, B
, C
, and D
but I want to merge only stuff
's changes to files A
and B
. It sounds like a job for git cherry-pick
but cherry-pick
only knows how to merge entire commits, not a subset of the files.
假设调用的 Git 提交stuff
对文件A
, B
, 进行了更改C
,D
但我只想合并stuff
对文件A
和B
. 这听起来像是一份工作,git cherry-pick
但cherry-pick
只知道如何合并整个提交,而不是文件的子集。
回答by Cascabel
I'd do it with cherry-pick -n
(--no-commit
) which lets you inspect (and modify) the result before committing:
我会用cherry-pick -n
( --no-commit
)来做,它让你在提交之前检查(和修改)结果:
git cherry-pick -n <commit>
# unstage modifications you don't want to keep, and remove the
# modifications from the work tree as well.
# this does work recursively!
git checkout HEAD <path>
# commit; the message will have been stored for you by cherry-pick
git commit
If the vast majority of modifications are things you don't want, instead of checking out individual paths (the middle step), you could reset everything back, then add in what you want:
如果绝大多数修改是您不想要的,而不是检查单个路径(中间步骤),您可以重置所有内容,然后添加您想要的内容:
# unstage everything
git reset HEAD
# stage the modifications you do want
git add <path>
# make the work tree match the index
# (do this from the top level of the repo)
git checkout .
回答by Michael Anderson
The other methods didn't work for me since the commit had a lot of changes and conflicts to a lot of other files. What I came up with was simply
其他方法对我不起作用,因为提交对许多其他文件有很多更改和冲突。我想出的很简单
git show SHA -- file1.txt file2.txt | git apply -
It doesn't actually add
the files or do a commit for you so you may need to follow it up with
它实际上并没有add
为您提供文件或提交,因此您可能需要跟进
git add file1.txt file2.txt
git commit -c SHA
Or if you want to skip the add you can use the --cached
argument to git apply
或者,如果您想跳过添加,您可以使用--cached
参数git apply
git show SHA -- file1.txt file2.txt | git apply --cached -
You can also do the same thing for entire directories
你也可以对整个目录做同样的事情
git show SHA -- dir1 dir2 | git apply -
回答by Tyrone Wilson
I usually use the -p
flag with a git checkout from the other branch which I find easier and more granular than most other methods I have come across.
我通常使用-p
带有来自另一个分支的 git checkout的标志,我发现它比我遇到的大多数其他方法更容易和更精细。
In principle:
原则上:
git checkout <other_branch_name> <files/to/grab in/list/separated/by/spaces> -p
example:
例子:
git checkout mybranch config/important.yml app/models/important.rb -p
You then get a dialog asking you which changes you want in "blobs" this pretty much works out to every chunk of continuous code change which you can then signal y
(Yes) n
(No) etc for each chunk of code.
然后你会得到一个对话框,询问你想要在“blob”中进行哪些更改,这几乎适用于每个连续代码更改块,然后您可以为每个代码块发出信号y
(是)n
(否)等。
The -p
or patch
option works for a variety of commands in git including git stash save -p
which allows you to choose what you want to stash from your current work
该-p
或patch
选项可用于各种Git中包括的命令git stash save -p
,它允许你选择你想从你目前的工作来隐藏什么
I sometimes use this technique when I have done a lot of work and would like to separate it out and commit in more topic based commits using git add -p
and choosing what I want for each commit :)
当我做了很多工作并且想将它分离出来并提交更多基于主题的提交时,我有时会使用这种技术,使用git add -p
和选择我想要的每次提交:)
回答by Mark Longair
Perhaps the advantage of this method over Jefromi's answeris that you don't have to remember which behaviour of git resetis the right one :)
也许这种方法比Jefromi 的答案的优势在于您不必记住git reset 的哪种行为是正确的:)
# Create a branch to throw away, on which we'll do the cherry-pick:
git checkout -b to-discard
# Do the cherry-pick:
git cherry-pick stuff
# Switch back to the branch you were previously on:
git checkout -
# Update the working tree and the index with the versions of A and B
# from the to-discard branch:
git checkout to-discard -- A B
# Commit those changes:
git commit -m "Cherry-picked changes to A and B from [stuff]"
# Delete the temporary branch:
git branch -D to-discard
回答by cminatti
Cherry pick is to pick changes from a specific "commit". The simplest solution is to pick all changes of certain files is to use
Cherry Pick 是从特定的“提交”中挑选更改。最简单的解决方案是选择某些文件的所有更改是使用
git checkout source_branch <paths>...
In example:
例如:
$ git branch
* master
twitter_integration
$ git checkout twitter_integration app/models/avatar.rb db/migrate/20090223104419_create_avatars.rb test/unit/models/avatar_test.rb test/functional/models/avatar_test.rb
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: app/models/avatar.rb
# new file: db/migrate/20090223104419_create_avatars.rb
# new file: test/functional/models/avatar_test.rb
# new file: test/unit/models/avatar_test.rb
#
$ git commit -m "'Merge' avatar code from 'twitter_integration' branch"
[master]: created 4d3e37b: "'Merge' avatar code from 'twitter_integration' branch"
4 files changed, 72 insertions(+), 0 deletions(-)
create mode 100644 app/models/avatar.rb
create mode 100644 db/migrate/20090223104419_create_avatars.rb
create mode 100644 test/functional/models/avatar_test.rb
create mode 100644 test/unit/models/avatar_test.rb
Sources and full explanation http://jasonrudolph.com/blog/2009/02/25/git-tip-how-to-merge-specific-files-from-another-branch/
来源和完整解释http://jasonrudolph.com/blog/2009/02/25/git-tip-how-to-merge-specific-files-from-another-branch/
UPDATE:
更新:
With this method, git will not MERGE the file, it will just override any other change done on the destination branch. You will need to merge the changes manually:
使用这种方法,git 不会合并文件,它只会覆盖在目标分支上所做的任何其他更改。您需要手动合并更改:
$ git diff HEAD filename
$ git diff HEAD 文件名
回答by techdreams
The situation:
情况:
You are on your branch, let's say master
and you have your commit on any other branch. You have to pick only one file from that particular commit.
你在你的分支上,假设master
你在任何其他分支上提交。您只需从该特定提交中选择一个文件。
The approach:
该方法:
Step 1:Checkout on the required branch.
第 1 步:在所需的分支上结帐。
git checkout master
Step 2:Make sure you have copied the required commit hash.
第 2 步:确保您已复制所需的提交哈希。
git checkout commit_hash path\to\file
Step 3:You now have the changes of the required file on your desired branch. You just need to add and commit them.
第 3 步:您现在在所需的分支上拥有所需文件的更改。您只需要添加并提交它们。
git add path\to\file
git commit -m "Your commit message"
回答by funroll
I would just cherry-pick everything, then do this:
我会挑选所有东西,然后执行以下操作:
git reset --soft HEAD^
Then I would revert the changes I don't want, then make a new commit.
然后我会还原我不想要的更改,然后进行新的提交。
回答by Indomitable
Use git merge --squash branch_name
this will get all changes from the other branch and will prepare a commit for you.
Now remove all unneeded changes and leave the one you want. And git will not know that there was a merge.
使用git merge --squash branch_name
这将从另一个分支获取所有更改,并为您准备提交。现在删除所有不需要的更改并保留您想要的更改。git 不会知道有合并。
回答by Alexey
I found another way which prevents any conflicting merge on cherry-picking which IMO is kind of easy to remember and understand. Since you are actually not cherry-picking a commit, but part of it, you need to split it first and then create a commit which will suit your needs and cherry-pick it.
我找到了另一种方法,可以防止在挑选樱桃时发生任何冲突的合并,IMO 有点容易记住和理解。由于您实际上不是挑选提交,而是挑选其中的一部分,因此您需要先拆分它,然后创建一个适合您需求的提交并挑选它。
First create a branch from the commit you want to split and checkout it:
首先从要拆分的提交创建一个分支并签出它:
$ git checkout COMMIT-TO-SPLIT-SHA -b temp
Then revert previous commit:
然后恢复之前的提交:
$ git reset HEAD~1
Then add the files/changes you want to cherry-pick:
然后添加您想要挑选的文件/更改:
$ git add FILE
and commit it:
并提交它:
$ git commit -m "pick me"
note the commit hash, let's call it PICK-SHA and go back to your main branch, master for example forcing the checkout:
注意提交哈希,我们称之为 PICK-SHA 并返回到你的主分支,例如强制结帐:
$ git checkout -f master
and cherry-pick the commit:
并挑选提交:
$ git cherry-pick PICK-SHA
now you can delete the temp branch:
现在您可以删除临时分支:
$ git branch -d temp -f
回答by nvd
Merge a branch into new one (squash) and remove the files not needed:
将一个分支合并到一个新分支(壁球)并删除不需要的文件:
git checkout master
git checkout -b <branch>
git merge --squash <source-branch-with-many-commits>
git reset HEAD <not-needed-file-1>
git checkout -- <not-needed-file-1>
git reset HEAD <not-needed-file-2>
git checkout -- <not-needed-file-2>
git commit