Git合并反复挤压

Git合并反复挤压,git,version-control,merge,Git,Version Control,Merge,我试图在git中有两个带有二进制文件的分支——一个是“开发”分支,另一个是“稳定”分支。在我想要将这些文件“发布”到稳定分支之前,开发分支可以对这些文件进行多次更改(如果相关的话,稳定分支将重命名这些文件) 我可以做一个普通的合并,这很好,但是保留了太多的历史-当拉动“稳定”分支时,来自“开发”分支的所有中间提交也会被拉动(因为它们是父提交)。但是我们讨论的二进制文件没有任何合理的合并策略(除了他们/我们的),因此开发分支上文件的实际历史记录是无用的。当我拉动“稳定”分支时,我得到: X----

我试图在git中有两个带有二进制文件的分支——一个是“开发”分支,另一个是“稳定”分支。在我想要将这些文件“发布”到稳定分支之前,开发分支可以对这些文件进行多次更改(如果相关的话,稳定分支将重命名这些文件)

我可以做一个普通的合并,这很好,但是保留了太多的历史-当拉动“稳定”分支时,来自“开发”分支的所有中间提交也会被拉动(因为它们是父提交)。但是我们讨论的二进制文件没有任何合理的合并策略(除了他们/我们的),因此开发分支上文件的实际历史记录是无用的。当我拉动“稳定”分支时,我得到:

X-------------------G stable / / a---b---c---d---e---f---g development 在我拉这个被压扁的稳定分支之后,我在我的存储库中得到了这个,这就是我想要的:

a---b---X---G 这让我得到了所有我不感兴趣的数据(c,d,e,f),作为奖励,我将释放b是分支中稳定版本的信息


每一次开发修订都会使存储库的大小增加约5MB(重新打包整个回购协议只会使其缩小约10%),而“稳定”分支几乎是免费的(数据已经存在)。我想从stable分支中提取一个新版本,只提取新的5MB,而不是从X更新到G下载25MB,因为我无法说我不关心c、d、e和f的内容。

这不是使用
合并--squash
的正确位置。使用它的一个好地方是在一个一次性的主题分支中,您将把它合并到您的主分支中,然后去掉它。在主题分支中完成的所有开发在主分支中显示为一个提交。在您的情况下,您应该正常地从开发分支合并,然后使用
git-rebase--interactive
挤压您想要的提交

是否可能以某种方式记录合并,而不生成具有两个父级的“合并提交”

如果我正确理解了这个问题,不。绝对不是

有没有可能让git只合并某个“范围”的修订版,比如SVN

git合并[commit hash]

或者,在拉取时,是否可以在不必从其他分支下载所有引用的情况下执行正常合并

见上一个问题的答案

或者我应该为有问题的文件提供一个自定义的合并驱动程序,只需将“他们的”版本重命名为“我们的”,从而解决冲突?我仍然担心——squash总是试图将整个历史合并,直到共同的父母,只解决我问题的一半


只是不要使用git merge--squash。这不是使用它的正确地方

您可以使用
git-rebase-i
(交互模式)来取消所有更改,只需将行更改为
m
meld
(更新:对于较新的git版本,键入
s
squash

您将拥有一个可以合并的提交。如果你想保留你的每一个步骤,你必须在你的黑客分支上创建另一个分支,然后再进行重基,这可以通过
git branch small-dirty-changes-i-not-want-anywhere-to-see来完成

所有这些都必须在尝试合并之前完成;逐步:

# on branch "hacking": hack commit hack commit hack commit

# create a reference to your history
$ git branch dirty-history

# sqash your commits by setting all lines to "meld"
$ git rebase -i

# checkout master or the branch you want to merge to
$ git checkout master

# merge your squashed commit
$ git merge hacking
# or: $ git pull hacking

      X stable
     /                   
a---b---c---d---e---f---g development
您可以使用以下步骤将上次提交从开发分支复制到稳定分支:

git checkout development@{0}  # get working tree from "development", detach HEAD
git reset --soft stable  # reposition detached HEAD on "stable"
git commit  # enter the appropriate commit message
git branch temp  # create a temporary branch "temp" at HEAD
git checkout temp  # get on the new temporary branch
git branch -M stable  # rename "temp" to "stable"
因此,你最终会:

      X-------------------G stable
     /                   
a---b---c---d---e---f---g development
      X-------------------G-----------J stable
     /                   
a---b---c---d---e---f---g---h---i---j development
如果您继续从事“发展”工作,例如:

您可以重复上述相同的git命令,最终将得到:

      X-------------------G stable
     /                   
a---b---c---d---e---f---g development
      X-------------------G-----------J stable
     /                   
a---b---c---d---e---f---g---h---i---j development

我是git新手,但它似乎是--squash是您想要的,您只需要以不同的方式处理分支

$ git merge --squash development
$ git branch -d development
$ git checkout -b development
# continue work on development branch
这将基本上截断开发分支的历史,下一次合并将只是您想要的。查看手册页,似乎
git branch-f development
可以执行与删除和重新创建分支相同的操作

正如我所说的,我对git还很陌生,所以我希望得到一些关于这个想法的反馈

有效区分稳定和开发分支,并将稳定中缺失的所有更改作为一个提交应用。有另一种方法可以做到这一点:

$ git checkout stable 
$ git diff stable development | git apply --index -   
$ git commit
提交之前,可以查看暂存文件。如果您想在应用了diff之后中止该过程,您可以使用basic命令从索引和工作目录中删除更改

$ git reset --hard
您可以重复该过程任意次数,因为每次需要合并时,您实际上只是区分两个分支的尖端

注意,这里有一个同样适用于其他答案的假设:除了来自开发分支的提交之外,稳定分支中没有提交。与常规合并不同,如果在两个分支中独立地更改同一行,这种方法不会产生冲突。相反,它只会用开发中的更改覆盖稳定分支中的更改


如果您担心这一点,那么每次在stable上提交时,都可以将合并的开发提交哈希范围放入提交消息中。这样,如果您需要回溯,您就有了一些记录。

谢谢您的回答!我不确定重新定基是否是我所需要的。我确实需要在“稳定”分支中记录一些历史记录,以便在“发布”之间来回切换。这就是我想要的:`D->SD | D | D->SD | D->S`但我只需要S分支的历史-我不关心D分支的历史。我需要解决的问题是,如何在不从D分支中提取所有父引用的情况下提取S分支(如果我理解正确,则重定基可消除所有以前的S提交,这不是我想要的)D->xddd->xddd->S`是的,我知道您需要从
$ git reset --hard