首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >git:如何重新定位到不同的基础(没有重基,没有合并!)

git:如何重新定位到不同的基础(没有重基,没有合并!)
EN

Stack Overflow用户
提问于 2017-02-18 18:06:49
回答 3查看 156关注 0票数 0

我想做一些类似于git-rebase的事情,但我不想在不同的基础上重播更改(介绍在我提交的基础上所做的更改)。我不在乎基本的内容。我不想合并任何东西。我想简单地创建提交A‘完全相同(完全相同的所有文件)提交A,但连接到另一个基础。这可行吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-02-18 19:13:11

编辑(在顶部添加答案,在水平线之后添加前面的答案,并添加更多的注释):显然,您希望保留原始树。

这里有一种使用普通Git命令的方法。

我们在这里假设您已经拥有要复制的提交的散列ID (或者它是指定分支的提示,或者有一个您可以轻松编写的名称)。首先检查这两种方法的输出:

代码语言:javascript
复制
git status

确保一切都是干净的(确保不会丢弃任何正在进行的工作),并且:

代码语言:javascript
复制
git rev-parse --show-cdup

如果打印任何../-es,那么就可以打印出多个../-es,以便您位于存储库的顶部。

现在您需要四个普通的Git命令:

代码语言:javascript
复制
git checkout target-branch

去你想让副本登陆的地方。然后:

代码语言:javascript
复制
git rm -rf .

这将移除索引和工作树中的所有内容。然后:

代码语言:javascript
复制
git checkout <hash-or-name> -- .

这将重新填充索引和工作树,使用所需的提交作为所有文件的源。(这就像我们一会儿会看到的read-tree -u。)最后:

代码语言:javascript
复制
git commit

若要使用当前索引进行新提交,请执行以下操作。

这是另一种方法,每一个PetSerAl的评论。主要的区别是我们不需要站在树的顶端:

代码语言:javascript
复制
git checkout target-branch
git read-tree --reset -u <hash-or-name>
git commit

read-tree操作将当前索引替换为来自给定提交的索引(散列ID或分支名称)。如果有的话,--reset部件丢弃未合并的条目(应该没有),并且需要允许-u-u指示Git用我们正在读取的索引中的文件替换所有工作树文件,并从工作树中删除不存在的任何文件。换句话说,这相当于git rm -rf . && git checkout <hash-or-name> -- .。我们使用一个管道命令(git read-tree),而不是两个面向用户的命令,我们不需要担心cd ../../或来自git rev-parse --show-cdup的任何东西。

切普纳的评论是一个关键问题:具有不同父链接的提交副本是不同的提交。因此,您想要更改原始提交的一些内容。那么问题是,确切地说,你想改变什么,你不想改变什么?

git cherry-pick的正确答案取决于这个问题的答案。那么,让我们看一看提交中的实际内容。

下面是来自Git存储库的一个真实的、实际的Git提交:

代码语言:javascript
复制
$ git cat-file -p HEAD | sed 's/@/ /'
tree afb30c6559dab43341512cd49dbfc446ac52474a
parent 076c05393a047247ea723896289b48d6549ed7d0
author Junio C Hamano <gitster@pobox.com> 1487368819 -0800
committer Junio C Hamano <gitster@pobox.com> 1487368819 -0800

Git 2.12-rc2

Signed-off-by: Junio C Hamano <gitster@pobox.com>

提交的内容是:

  • 树ID:这是源快照。
  • 一些父is,虽然通常只有一个:这是您肯定想要更改的东西。
  • 作者(姓名、电子邮件和时间戳):提交的作者。
  • 提交者:和作者一样,但是现在把这个提交放到这个存储库中的人。(这对于电子邮件修补程序尤其有用,这就是Linux在Git普及之前的早期工作方式。)
  • 提交消息。

如果保留原始树,则源快照将与复制的提交中的快照完全相同。如果这是您想要的,您就不能使用git cherry-pick来复制提交,因为樱桃选择是针对树由于新的基而必须改变的情况而设计的。

git cherry-pick命令将原始提交快照转换为diff (通过将其与其父文件进行比较),然后将diff应用于当前提交,并根据结果进行新的提交。所以这个新的提交通常有一个不同的tree ID,如果这是你想要的--这是大多数人想要的--那么就这么做。

尽管并非闻所未闻,但想要保护原始树还是相当罕见的。为此,您必须使用大量面向用户的常规命令,或者使用“管道”命令(如PetSerAl的评论中的命令)。您可以使用的另一个管道命令是git commit-tree,它允许您将特定的树ID和父ID集写入新提交。(您可以通过6个Git环境变量保留原始作者和提交者的名称、电子邮件和时间戳--尽管这种特殊的愿望也很少见。)

票数 2
EN

Stack Overflow用户

发布于 2017-02-18 18:19:02

正如R0AMNARMY的评论中所述,您希望使用樱桃采摘。只需在要添加给定提交的分支中使用原始提交的SHA即可。

代码语言:javascript
复制
git checkout your-different-branch
git cherry-pick SHA-from-original-commit
票数 1
EN

Stack Overflow用户

发布于 2017-02-18 20:13:49

我想简单地创建提交A‘完全相同(完全相同的所有文件)提交A,但连接到另一个基础。这可行吗?

代码语言:javascript
复制
git update-ref refs/heads/another $(
        git log -1 --pretty=%B A | git commit-tree -p another A
)

如果您已经检查过another,请使用git reset --hard进行检查。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42318808

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档