如何在一个分支中创建快照的副本(提交)到git中的另一个分支? [英] How to create copy of a snapshot (commit) in a branch onto another branch in git?
问题描述
当我开始使用Git时,我了解到的第一件事就是Git不会将信息存储为基于文件的更改(补丁)列表,而是存储为快照流.提交是所有存储库的快照.
When I started to use Git, one of the first things I learned about it is that Git does not store information as list of file-based changes (patches), but as a stream of snapshots. A commit is a snapshot of all the repository.
考虑一下,我们在存储库Branch_A和Branch_B中有两个分支.它们之间的关系没有关系,可能非常简单也可能非常复杂(与其他分支合并...).只是这样代表他们:
Consider we have two branches in a repository Branch_A and Branch_B. No mater the relation between them, it may be very simple of very complicated (merge with others branches...). Just represent them like this:
A <--- ... -- I <----- J <----- K Branch_A
M <------ N <----- O <----- P Branch_B
出于某些原因,我希望Branch_A的下一个提交恰好是Branch_B中的提交P的状态(快照).
For some reasons, I want that the next commit of Branch_A be exactly the state (the snapshot) of the commit P in Branch_B.
是否有git命令来执行此操作?
Is there a git command to do this ?
我不能使用常规"合并,因为我不想解决P和K之间的冲突. 我不能对选项"theirs"使用递归合并,因为它将所有与P不冲突的文件保留在K中,即使它们不存在于P中.
I can't use a "normal" merge, because I don't want to resolv conflicts between P and K. I can't use a recursive merge with the option "theirs" because it will keep all the files in K that do not conflicts with P, even if they do not exist in P.
我可以这样:
cd /path/to/myrepo;
git checkout Branch_B
cp -R * /path/to/save_branch_b_state
git checkout Branch_A
rm -rf *
cp -R /path/to/save_branch_b_state . (In fact, I copy everything but the .git directory)
git add *
git commit
但是我想有一个git命令可以做到这一点.
But I imagine there is a git command to do this.
推荐答案
没有一个单个 git命令可以执行此操作,但是只需执行几个命令即可.
There is no one single git command to do it but you can do it with just a few commands.
第一个问题是:您是否希望它至少类似于合并(在这种情况下,它实际上将是合并)?也就是说,您希望提交图是什么样子?它应该显示来自branch_B
(提交P
所在的地方)的某种联系吗:
The first question, though, is: do you want this to at least resemble a merge (in which case, it will really be a merge)? That is, what do you want the commit graph to look like—should it show some kind of linkage from branch_B
(where commit P
lives), a la:
A <--- ... -- I <----- J <----- K <--- * Branch_A
/
M <------ N <----- O <----- P Branch_B
您的新提交在哪里*
?还是您希望它完全独立?
where *
is your new commit? Or do you want it to be totally independent?
低级命令git commit-tree
将使用任意的父级年龄进行新提交(您为父级ID提供-p
,一条消息和一个现有的"tree"对象).它将打印出最终的提交对象ID.因此,请使用低级命令执行此操作:
The low-level command git commit-tree
will make a new commit with arbitrary parent-age (you supply the parent IDs with -p
, a message, and an existing "tree" object). It prints the resulting commit-object ID. So to do this with the low level command:
tree=$(git rev-parse B^{tree}) # or similar to find the tree ID
commit=$(git commit-tree -p ... -m message $tree) # or use -F, or stdin
然后将Branch_A
设置为指向$commit
(使用git branch
或git update-ref
).可以将其转换为单行外壳程序,并因此作为git别名完成,但这有点棘手,可能值得将其作为外壳程序脚本.仅选择一个ID作为父代,使您的新提交成为常规(非合并)提交,或者选择多个ID使其成为合并;如果要合并,请根据您希望--first-parent
以后的工作方式选择父ID顺序.
then set Branch_A
to point to $commit
(using git branch
or git update-ref
). This can be turned into a one line shell thing and hence done as a git alias, but it's a bit tricky and probably deserves to be a shell script. Choose just one ID as parent to make your new commit a regular (non-merge) commit, or multiple IDs to make it a merge; if you do make it a merge, choose the parent ID ordering based on how you want --first-parent
to work in the future.
或者,您可以使用更高级别的git命令来实现.例如,如果您不希望它成为(和类似于)合并,则可以简单地从Branch_A
开始,擦除所有内容(从索引和工作树中删除整个树) ,重新填充提交P
中的所有内容(基于提交P
创建新的索引内容和工作树),然后提交:
Or, you can do it with somewhat higher level git commands. For instance, if you don't want it to be (and resemble) a merge, you can simply start on Branch_A
, erase everything (remove the entire tree from the index and work-tree), repopulate everything from commit P
(create new index contents and work-tree based on commit P
), and then commit:
$ git checkout Branch_A
$ git rm -rf . # cd to top dir first if needed
$ git checkout Branch_B -- . # index and work tree = commit P
$ git commit
或者,将上述操作作为真正的合并进行:请参见此问题的答案.
Or, do the above as a real merge: see the answer to this question.
这篇关于如何在一个分支中创建快照的副本(提交)到git中的另一个分支?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!