git 在合并期间什么时候会丢失更改?

Pau*_*ulJ 5 git version-control rebase

让我们说:

  1. 我们有一个 master 分支,其中一个同事不小心添加了一系列本A B C应属于新功能的提交(我们称之为)。
  2. 我发现了这一点,我告诉他将这些提交移动到一个新分支,但保留稍后在 master 中完成的其他无关提交。我向他发送了我问的这个问题,并告诉他按照回复:git: how to move a branch's root two commits back
  3. 几天后,当新功能分支准备就绪时,我将其合并到 master 中。
  4. 解决合并中的所有冲突后,我提交更改...
  5. ...我发现那些第一次提交(A B C那些)已经消失了。
  6. 我问我的同事,他说“他认为”他使用链接中提到的方法移动了这些更改(基本上:检查最后一个常见提交,然后git cherry-pick仅选择我们稍后想要的提交),但他记不清了。
  7. 我检查了回购的历史,A B C 在特性分支,在开始。他们看起来像是从 master 成功迁移过来的。

鉴于上述情况,谁能解释为什么 git 丢失了这些更改?(我个人的理论是 git 以某种方式“记住”我们已经撤消了提交A B C,所以当它们来自新的功能分支时,git 决定不合并它们。编辑:对不起,如果这个解释听起来太像“神奇的想法”,但是我不知所措。我欢迎任何尝试用更专业的术语来解释这个解释,如果它是对的)。

很抱歉无法提供更多细节,但我没有亲自在 repo 中进行这些更改,因此无法提供所做工作的确切细节。

编辑:好的,按照这里的建议,我让我的同事git reflog在他的机器上执行,所以我在这里粘贴结果。回到我之前的(链接的)问题,我们有一棵这样的树:

A - B - C - D - E - F  master
            \ 
             \- G - H  new feature branch
Run Code Online (Sandbox Code Playgroud)

我们想将 B 和 C 移动到新的功能分支。

所以,git reflog他发给我的就是这里。提交5acb457将对应于上图中的“提交 A”:

4629c88 HEAD@{59}: commit: blah
f93f3d3 HEAD@{60}: commit: blah
57b0ea7 HEAD@{61}: checkout: moving from master to feature_branch
4b39fbf HEAD@{62}: commit: Added bugfix F again
4fa21f2 HEAD@{63}: commit: undid checkouts that were in the wrong branch
1c8b2f9 HEAD@{64}: reset: moving to origin/master
5acb457 HEAD@{65}: checkout: moving from 5acb4576eca4b44e0a7574eea19cca067c039dc5 to master
5acb457 HEAD@{66}: checkout: moving from master to 5acb4576eca4b44e0a7574eea19cca067c039dc5
1c8b2f9 HEAD@{67}: checkout: moving from 1c8b2f9bf54ca1d80472c08f3ce7d9028a757985 to master
1c8b2f9 HEAD@{68}: rebase: checkout master
5acb457 HEAD@{69}: checkout: moving from master to 5acb4576eca4b44e0a7574eea19cca067c039dc5
1c8b2f9 HEAD@{70}: checkout: moving from 5acb4576eca4b44e0a7574eea19cca067c039dc5 to master
5acb457 HEAD@{71}: checkout: moving from master to 5acb4576eca4b44e0a7574eea19cca067c039dc5
1c8b2f9 HEAD@{72}: merge origin/master: Fast-forward
5acb457 HEAD@{73}: checkout: moving from master to master
5acb457 HEAD@{74}: checkout: moving from 5acb4576eca4b44e0a7574eea19cca067c039dc5 to master
5acb457 HEAD@{75}: checkout: moving from undo_branch to 5acb4576eca4b44e0a7574eea19cca067c039dc5
5acb457 HEAD@{76}: checkout: moving from master to undo_branch
1c8b2f9 HEAD@{77}: checkout: moving from undo_branch to master
525dbce HEAD@{78}: cherry-pick: Bugfix F
a1a5028 HEAD@{79}: cherry-pick: Bugfix E
32f8968 HEAD@{80}: cherry-pick: Feature C
8b003cb HEAD@{81}: cherry-pick: Feature B
5acb457 HEAD@{82}: checkout: moving from 5acb4576eca4b44e0a7574eea19cca067c039dc5 to undo_branch
5acb457 HEAD@{83}: checkout: moving from master to 5acb4576eca4b44e0a7574eea19cca067c039dc5
1c8b2f9 HEAD@{84}: checkout: moving from 1c8b2f9bf54ca1d80472c08f3ce7d9028a757985 to master
1c8b2f9 HEAD@{85}: pull origin HEAD:master: Fast-forward
5acb457 HEAD@{86}: checkout: moving from master to 5acb4576eca4b44e0a7574eea19cca067c039dc5
5acb457 HEAD@{87}: reset: moving to 5acb4576eca4b44e0a7574eea19cca067c039dc5
1c8b2f9 HEAD@{88}: merge origin/master: Fast-forward
5acb457 HEAD@{89}: reset: moving to 5acb4576eca4b44e0a7574eea19cca067c039dc5
1c8b2f9 HEAD@{90}: checkout: moving from 5acb4576eca4b44e0a7574eea19cca067c039dc5 to master
5acb457 HEAD@{91}: checkout: moving from master to 5acb4576eca4b44e0a7574eea19cca067c039dc5
1c8b2f9 HEAD@{92}: merge origin/master: Merge made by the 'recursive' strategy.
7b912cd HEAD@{93}: checkout: moving from 7b912cdf33843d28dd4a7b28b37b5edbe11cf3b9 to master
7b912cd HEAD@{94}: cherry-pick: Bugfix F
df7a9cd HEAD@{95}: cherry-pick: Bugfix E
d4d0e41 HEAD@{96}: cherry-pick: Feature C
701c8cc HEAD@{97}: cherry-pick: Feature B
5acb457 HEAD@{98}: checkout: moving from master to 5acb4576eca4b44e0a7574eea19cca067c039dc5
22ecc3a HEAD@{99}: checkout: moving from 5acb4576eca4b44e0a7574eea19cca067c039dc5 to master
5acb457 HEAD@{100}: checkout: moving from master to 5acb4576eca4b44e0a7574eea19cca067c039dc5
22ecc3a HEAD@{101}: commit: bugfix E
3b568bc HEAD@{102}: checkout: moving from feature_branch to master
57b0ea7 HEAD@{103}: commit: blah
152c5b9 HEAD@{104}: checkout: moving from master to feature_branch
3b568bc HEAD@{105}: commit: bugfix D
fe3bbce HEAD@{106}: checkout: moving from feature_branch to master
152c5b9 HEAD@{107}: commit: blah
2318ebc HEAD@{108}: commit: blah
cc5ea32 HEAD@{109}: commit: blah
a5c2303 HEAD@{110}: commit: blah
544a99a HEAD@{111}: commit: blah
299f86a HEAD@{112}: commit: Feature G
fe3bbce HEAD@{113}: checkout: moving from master to feature_branch
fe3bbce HEAD@{114}: commit: Feature C
3852e71 HEAD@{115}: commit: Feature B
5acb457 HEAD@{116}: merge origin/master: Fast-forward
Run Code Online (Sandbox Code Playgroud)

任何人都可以理解cherry-pick连续的4秒吗?我怀疑他并没有真正做这git cherry-pick master~3件事,特别是不是那~3部分(当我第一次看到它时,我承认它也让我失望)。

Mar*_*Liu 5

提交 A、B 和 C 丢失的原因是您与同事共享的链接所做的。让我们通过下图来说明:

\n

1. 假设您的同事的原始提交历史记录为

\n
...X---A---B---C---D---E\xc2\xa0 master\n
Run Code Online (Sandbox Code Playgroud)\n

2. 移动ABCfeature分支。feature因此,您的同事从 master (提交E)或任何提交创建了一个新分支。并通过以下步骤进行变基:

\n
git checkout -b feature\ngit cherry-pick master~5 master~2\n\n...X---A---B---C---D---E\xc2\xa0 master\n                        \\\n                         A'---B'---C' feature \n
Run Code Online (Sandbox Code Playgroud)\n

3. 修改master分支为,

\n
git checkout X\ngit cherry-pick master~2..master\ngit branch -f master\ngit checkout master\n
Run Code Online (Sandbox Code Playgroud)\n

提交结构将如下所示:

\n
...X---D---E\xc2\xa0 master\n     \\\n       A'---B'---C' feature \n
Run Code Online (Sandbox Code Playgroud)\n

所以直接原因就是命令git cherry-pick master~2..master。它将 rebase commitDE直接在 commit 上X,因此您可以\xe2\x80\x99t find ABC在 master 分支上。

\n

更新:

\n

根据git flog,这些 HEAD 信息似乎不足以显示您的同事做了什么。并且feature分支似乎是从提交结帐C而不是D通过

\n
3b568bc HEAD@{105}: commit: bugfix D\nfe3bbce HEAD@{106}: checkout: moving from feature_branch to master\n152c5b9 HEAD@{107}: commit: blah\n2318ebc HEAD@{108}: commit: blah\ncc5ea32 HEAD@{109}: commit: blah\na5c2303 HEAD@{110}: commit: blah\n544a99a HEAD@{111}: commit: blah\n299f86a HEAD@{112}: commit: Feature G\nfe3bbce HEAD@{113}: checkout: moving from master to feature_branch\nfe3bbce HEAD@{114}: commit: Feature C\n
Run Code Online (Sandbox Code Playgroud)\n

所以结构应该是:

\n
A---B---C---D---E  master\n         \\\n          G---H feature\n
Run Code Online (Sandbox Code Playgroud)\n

如果您只想更改提交结构,例如:

\n
A ---D---E  master\n \\\n  B---C---G---H feature\n
Run Code Online (Sandbox Code Playgroud)\n

您可以将您的master分支和分支重置为原始分支,然后在分支feature上挑选提交,详细信息如下:master

\n
git checkout master\ngit reset --hard <original commit id for E>\ngit checkout feature \ngit reset --hard  <original commit id for H>\ngit checkout master\ngit checkout <commit id for A>\ngit cherry-pick master~4..master~2 #To make the commits as A---D---E (drop B and C)\ngit branch -f master\ngit checkout master\n
Run Code Online (Sandbox Code Playgroud)\n