所以我正在和一些队友一起开展一个项目,我已经改变了他们的变化,但有没有办法删除他们的提交(只是在本地 - 不打算用这种方式推送)并随意添加它?
**编辑:澄清,我不想将提交与我的提交相结合,我只想让它好像从未发生过提交(从提交中删除任何更改等)
Commit A: Commit that both of us got out
Commit B: His commit <- want to locally remove just this commit
Commit C: My commit
我曾考虑过制作一个分支,只是将我的提交放在分支上,而不是将其更改到该分支上,但我想知道是否有更简洁的方法不涉及单独的分支?
提前致谢!
答案 0 :(得分:4)
不要害怕树枝!特别是分支分支名称,因为the word "branch" is ambiguous in Git - 非常便宜,几乎是免费的。对于Git,创建一个新分支包括将一个提交哈希ID写入一个文件, 1 并删除一个分支包括删除该文件。
虽然价格不那么便宜,但它们本身就是承诺。每个提交都只有一个“真实名称”,即大丑陋的哈希ID,face0ff...
或cafedad...
或其他。每个提交都记录其父提交ID,因此您(和Git)可以向后工作,从分支上的 last 提交开始,找到 all < / em>分支上的提交。这些提交是永久性的,不变的。可以更改的不是提交,而是分支名称。
你绘制的内容有三次提交,但你没有明确表达彼此之间的关系。通过仅记录父母,在每次提交中记录这种关系,这是一种父/子事物。 2 因此,假设(合理地,我认为)提交A
首先出现,然后是B
,然后是C
,你拥有的是:
A <- B <- C <-- branch
即,分支名称branch
指向您的提交C
,您的提交C
指向B
(“B是我的父母”,说C)和B
指向A
。这些父指针都不能改变,但分支名称可以改变,并且使新的分支名称如此便宜,它可能也是免费的。
让我们创建一个新的名称并将其指向C
:
$ git checkout -b temp
现在我们有:
A--B--C <-- branch, HEAD -> temp
我在此处放置HEAD ->
表示当前分支是temp
,即使有两个分支名称都指向提交C
。
现在你可以做的是复制 C
到一个新提交,它主要是C
,但不完全一样。我们将调用副本C'
。在C'
中,我们需要这两个主要区别:
A
,而不是B
B
更改为C
的内容,并将这些更改作为修补程序应用到A
,而不是B
。复制这样的提交,然后移动分支名称的命令是git rebase
:
$ git rebase --onto HEAD~2 HEAD~1 # we'll explain these later
rebase命令复制每个“rebased”提交,在这种情况下只提交C
。然后它将当前分支名称移动到指向副本:
A--B--C <-- branch
\
`---C' <-- HEAD -> temp
请注意,原始提交C
仍然在那里,它仍然位于分支branch
的顶端。我们在制作副本时将其从temp
放弃,但branch
仍然记得它。
现在,您可以孤立地测试更改:C'
在没有B
的情况下是否正常工作?如果是这样,C
可能会引发B
中出现的任何问题,因为C'
vs A
与C
vs {几乎“相同” {1}}。
1 这是一个实现细节,分支名称也可以存储为多个文件而不是每个文件一个,但它应该让你知道如何廉价的分支真的是。
2 这是必要的,因为在您创建提交时,它具有 no 子项。一旦你创建了提交,它就是永久性的,不变的,所以它不能记录它的子节点。它的孩子还不存在!但是,只要有一个孩子存在,那个孩子就有了它的父母,那个孩子的父母也是永久性的,不变的,所以孩子可以而且确实记录了它的父母。
B
和HEAD~2
每当你想在Git中识别特定的提交时,你可以给它原始的SHA-1哈希。例如,您可以从HEAD~1
输出中剪切并粘贴这些内容。但您也可以使用符号名称,例如分支或标记名称,或特殊名称git log
。这些符号名称只是解析为提交ID:
HEAD
您可以缩写这些内容,以便$ git rev-parse HEAD
de2efebf7ce2b308ea77d8b06f971e935238cd2f
或face0ff
可用,如果实际ID以此开头。
您还可以使用 relative 名称,该名称取名为cafebabe
。所以~number
和HEAD~2
都意味着同样的事情。 de2efeb~2
后缀表示“返回一些父母”,回访的父母数量是~
之后的任何内容。
由于~
始终是当前提交,HEAD
表示“返回一个父母”,而HEAD~1
表示“返回两个父母”。从HEAD~2
开始,返回一位家长会获得C
,而返回两位则会获得B
。
因此:
A
表示“复制,以便我们在--onto HEAD~2
之后添加”,同时:
A
在这种情况下,表示“不要复制提交HEAD~1
或更早” - 只留下提交B
。
答案 1 :(得分:1)
首先,尝试在存储库中获取所有提交
尝试 - &GT;的 git log
强>
它显示对存储库的所有提交。
您的团队将提供所有不同的提交和参考编号:
例:
- &gt;提交4406fbc67a665a1e78c9ac2698164986b81bed13
让你想改变第一次提交只是引用那个。像这样
git checkout 4406fb(this is the commit reference no) SplashActivity.java(this will be particular file name)
答案 2 :(得分:1)
您可以将提交重新绑定到您想要作为父级的提交。
在提交C:
时git rebase --onto <a_hash> <b_hash>
这不会“删除”B但它不再是C历史的一部分,这似乎是你的目标。
您可以通过重新贴回B来“添加回来”。
git rebase --onto <b_hash> <a_hash>