如何在一个分支中创建快照的副本(提交)到git中的另一个分支? [英] How to create copy of a snapshot (commit) in a branch onto another branch in git?

查看:87
本文介绍了如何在一个分支中创建快照的副本(提交)到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 branchgit 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆