Git 从主服务器获取当前差异,并将其转换为单个提交,而无需将每个提交应用到彼此之上
我想在master之前进行一些分支,即X提交,基本上快照当前的差异,并从中创建一个提交 通常我使用Git 从主服务器获取当前差异,并将其转换为单个提交,而无需将每个提交应用到彼此之上,git,Git,我想在master之前进行一些分支,即X提交,基本上快照当前的差异,并从中创建一个提交 通常我使用git-rebase-I,压缩除最新提交之外的所有提交,这样就可以了 然而,如果在修复过程中出现了与重定基础的冲突或问题,我必须手动处理。我不一定要在每个提交的基础上应用每个提交—相反,我希望在分支负责人和主节点之间获得当前的差异,并从中创建一个提交 我已经通过手动区分我的整个分支和主分支,创建mychanges.diff,然后将其应用到一个干净的分支,但是感觉git中应该有一种本地的干净方法,通过
git-rebase-I
,压缩除最新提交之外的所有提交,这样就可以了
然而,如果在修复过程中出现了与重定基础的冲突或问题,我必须手动处理。我不一定要在每个提交的基础上应用每个提交—相反,我希望在分支负责人和主节点之间获得当前的差异,并从中创建一个提交
我已经通过手动区分我的整个分支和主分支,创建
mychanges.diff
,然后将其应用到一个干净的分支,但是感觉git中应该有一种本地的干净方法,通过应用每个提交来不重新基定,而是快照当前状态并创建一个与master不同的提交。我相信您想要的是git merge--squash
:
git checkout master
git merge --squash otherbranch
[resolve any conflicts if necessary, then]
git diff --cached # to see what you're about to commit
git commit # to make a single non-merge commit on master
比较长的
差异不是快照,因此这里有一个基本的不匹配。让我试试古老的温度类比。假设我告诉你今天这里比昨天暖和十度。(虽然实际上差不多:-)现在我有一个问题要问你:今天的温度是多少?或者,相当于,昨天的温度是多少
快照是绝对的。如果我告诉你温度是68˚F/20˚C,或者比昨天高10˚F,或者昨天是58˚F,那么这两条信息就足够了。一个快照或一个差异是不够的:您需要两个快照,或者一个快照和一个差异。(请注意,无限多的差异永远不够:您始终需要序列中的某个位置至少有一个快照。否则,可能会有一些东西在开始时是什么样子,从未更改过,您根本看不到它。)
不过,我认为你所描述的情况是这样的:
C--D--E--F--G <-- branch
/
....--A--B--H <-- master
但是如果H
确实存在,那么您可能希望将B
-vs-G
的更改与B
-vs-H
的更改结合起来,这样您就不会消除在一开始进行H
时所做更改的影响。组合这些更改的命令是git merge
一个普通的完全合并,你可以通过git checkout master得到它;git合并分支机构将:
- 查找合并基,在本例中为commit
李>B
- 将合并基提交与当前分支tip
区分,以查找“我们的”更改李>H
- 将相同的合并基础提交与“他们的”(仍然是我们的,但在合并期间
)提交--theres
,以查找“他们的”更改;及G
- 尝试合并这些更改
M
和S
之间的关键区别在于S
只指向提交H
,而根本不指向提交G
。(S
的默认提交消息文本也不同,但由于在git commit
打开提交消息编辑器时有机会替换此文本,因此这种差异并不重要。)
如果commitH
不存在,那么git merge--squash
操作仍然执行完全相同的过程。合并基仍然是提交B
:
C--D--E--F--G <-- branch
/
....--A--B <-- master (HEAD)
注意,在像这样使用gitmerge--squash
之后,分支branch
几乎肯定会被完全删除。除非您将commitS
从master
剥离,否则不应返回到它并进行更多的提交
(您可能想知道为什么git merge--squash
会首先停止。唯一合理的答案是,这是一次历史事故,其行为从那时起一直保持不变。如果它在默认情况下没有停止,您可以随时运行git merge--squash--no commit
,只要您希望它停止。但是squash merge的第一个实现是有效的通过让git merge
在它运行自己的内部git commit
之前提前退出,这样编码就更容易了。冲突的merge和--no commit
案例执行另一个步骤,即在内部状态文件中记录合并正在进行;然后它们退出。当运行git commit
时,G它要么注意到“正在合并”状态文件,要么不注意,这取决于git merge
是否创建了它。然后,它要么因为没有记录状态而进行正常的非合并提交,要么因为有记录的合并状态而进行合并提交。)
1有多个Git命令可以实现此结果。没有一个命令可以一步完成此操作:至少需要两个Git命令才能完成此操作。即使使用
Git merge--squash
,情况也是如此
C--D--E--F--G <-- branch
/
....--A--B--G' <-- master (HEAD)
C--D--E--F--G <-- branch
/ \
....--A--B--H------------M <-- master (HEAD)
C--D--E--F--G <-- branch
/
....--A--B--H------------S <-- master (HEAD)
C--D--E--F--G <-- branch
/
....--A--B <-- master (HEAD)
C--D--E--F--G <-- branch
/
....--A--B--S <-- master (HEAD)