在GitHub上更改作者信息后,应该执行哪些本地操作?
我想从提交到GitHub repo的过程中删除个人电子邮件地址,因此我遵循Git Bash,它在临时克隆repo中使用在GitHub上更改作者信息后,应该执行哪些本地操作?,git,rebase,Git,Rebase,我想从提交到GitHub repo的过程中删除个人电子邮件地址,因此我遵循Git Bash,它在临时克隆repo中使用Git筛选器分支更新受影响的提交,最后运行以下命令: git push --force --tags origin 'refs/heads/*' 现在,在GitHub上,回购协议看起来是正确的,电子邮件已经清理干净。然而,我对Git还不熟悉,不确定我需要做什么后续工作来同步我的本地副本 当我尝试拉取时,会出现错误“拒绝合并不相关的历史记录” 在此之前,我没有在本地进行任何更改,
Git筛选器分支
更新受影响的提交,最后运行以下命令:
git push --force --tags origin 'refs/heads/*'
现在,在GitHub上,回购协议看起来是正确的,电子邮件已经清理干净。然而,我对Git还不熟悉,不确定我需要做什么后续工作来同步我的本地副本
当我尝试拉取时,会出现错误“拒绝合并不相关的历史记录”
在此之前,我没有在本地进行任何更改,所以可能最简单的方法就是删除我的本地回购协议,然后再次签出该项目,但据我所知,这不是最佳做法或最灵活的方式
似乎我需要重新审视重写的历史,可能是这样的:
git pull --rebase
这是最好的办法吗?如果没有,是什么
旁注:我在IntelliJ IDEA中工作,理想情况下,仅将cmd行用于编写更改脚本等不寻常的事情,其Pull对话框没有Rebase选项,但Update Project有,所以我实际上就是这么做的。这是对的吗?无论您选择什么过程来同步本地回购,最终结果都是一样的:两个回购都具有相同的历史记录。在这种情况下,本地版本将被远程版本覆盖 因此,由于您没有本地更改需要保留,很可能没有什么比您考虑的再次克隆项目更干净、更快的了。我会说去做吧
(作为旁注,我看不出这是一种不好的做法的任何原因。您预见到了什么具体问题?当您像这样重写历史时,您可以而且您的案例确实得到了一个新的、不同的存储库。在这种情况下,旧存储库的所有现有克隆仅可用于旧存储库。现在,您只需创建新存储库的新克隆,这是一个新项目,您永远不应该连接到旧项目:这两个项目不再兼容,提交也不能再从一个项目转移到另一个项目 这是一个复杂现实的简化视图,但它应该满足您的情况。如果你想了解现实,请继续阅读 Git主要关心提交,但提交到底是什么? Git存储库的本质是一对数据库。大型数据库包含所有提交,或者更准确地说,包含所有Git对象。(Git对象有四种类型:commit、tree、blob和annotated tag。tree和blob是commit在其内部存储文件的方式,而annotated tag对象只是用来保存带注释的标记数据。)每个唯一的Git对象都有一个唯一的散列ID,因此每个commit都有自己唯一的散列ID,与其他每次commit不同 所有这些散列ID不仅是唯一的,而且是通用的。这意味着宇宙中任何地方的每个Git都使用相同的GUID进行提交 Git实际实现这一点的方式是,ID是提交内容的加密校验和。这意味着在提交中几乎不可能更改任何内容:如果您确实设法更改了某些内容,那么您将得到一个新的、不同的提交,并使用一个新的、不同的哈希ID。给定哈希ID,Git可以检查它是否有对象。如果是这样,它可以检索对象。如果没有,您的Git可以向其他Git(有对象的Git)请求完整的对象,并将结果对象填充到它的大数据库中 每当我们有散列ID并且实际对象在数据库中时,我们就说我们有一个指向该对象的指针。这些指针让我们可以找到提交(或其他Git对象,但主要是使用提交) 在任何情况下,提交的实际内容通常都很短:每次提交都会保存该提交文件快照的哈希ID,这是您要永久保留的数据,再加上一组元数据,如您的姓名和电子邮件地址。不过,每次提交的元数据片段之一是提交的父哈希ID(如果提交是合并提交,则为复数ID)。因此,每个提交都通过散列ID指向其父级 我们可以画出这个,如果我们使用单大写字母来表示提交,它甚至看起来有点合理。(当然,我们很快就会用完字母,这就是Git使用那些大而难看的散列ID的原因。)下面是一个存储库的示例,其中只有一个
master
和八个提交,它们的散列ID是a
到H
:
A <-B <-C ... <-F <-G <-H <--master
现在,两个分支都指向commitH
。我们选择一家分行“开启”,并使用git checkout
将我们的HEAD
附加到该分行:
...--F--G--H <-- master, develop (HEAD)
现在,真正聪明的事情发生了。现在Git将I
的散列ID写入附加到的分支名称头中:
...--F--G--H <-- master
\
I <-- develop (HEAD)
你的过滤器会改变你的作者信息。提交A
成为新提交A'
:
D--E <-- master
/
A--B--C
\
F--G <-- feature
A' [in progress]
这会一直重复到E
和G
:
D--E <-- master
/
A--B--C
\
F--G <-- feature
D'-E' <-- (replacement for master)
/
A'-B'-C'
\
F'-G' <-- (replacement for feature)
D--E感谢您在@torek发布的内容丰富的帖子,有助于巩固我的理解。但我不明白这一点:“您现在只需对新存储库进行新的克隆,这是一个新项目,您永远不应该连接到旧项目:这两个项目不再兼容,提交也不能再从一个项目转移到另一个项目。”这不是GitHub的建议,也不是我所做的,至少从字面上说是这样。GitHub的process force推送临时repo,覆盖原始文件,在本地,它是同一个项目。原来的提交已经不存在了,新的工作是基于新版本的,但它是相同的回复。@enigment:我这里有我祖父的斧头。它只有两部分,一个铁制的斩头和一个木制的把手。我父亲在把手坏了的时候换了它,我去年换了它的头。我祖父的斧头没有留下任何零件。这把斧子真的是我祖父的斧子吗?回答那个问题
D--E <-- master
/
A--B--C
\
F--G <-- feature
D--E <-- master
/
A--B--C
\
F--G <-- feature
A' [in progress]
D--E <-- master
/
A--B--C
\
F--G <-- feature
A'-B' [in progress]
D--E <-- master
/
A--B--C
\
F--G <-- feature
D'-E' <-- (replacement for master)
/
A'-B'-C'
\
F'-G' <-- (replacement for feature)