git:推送单个提交,使用 rebase 重新排序,重复提交
git: Pushing Single Commits, Reordering with rebase, Duplicate Commits
我想将多个单个提交推送到 git 远程仓库。我按照杰夫在这里找到的答案这样做:
How can I pushing specific commit to a remote, and not the previous commits?
我想推送的提交不在最前面,所以我必须先使用 rebase 重新排序提交,我使用了这些指令来这样做:
http://gitready.com/advanced/2009/03/20/reorder-commits-with-rebase.html
基本上我已经完成了:
git clone
git commit
git commit
...
git pull
git rebase -i HEAD~3
git push origin <SHA>:master
我在执行此操作时遇到错误。所以我开始更深入地研究这个问题。我发现如果我在变基后进行第二次 git 拉取,我的日志中会出现重复提交,例如:
git clone
git commit
git commit
...
git pull
git log --pretty=format:"%h - %an : %s" // log before rebasing
git rebase -i HEAD~3
git pull
git log --pretty=format:"%h - %an : %s" // log after rebasing
git pull
git log --pretty=format:"%h - %an : %s" // log after rebasing after pulling
所以我发布了这个问题:
Roger 的回答让我想到了这个问题:为什么我在变基和拉动后看到重复提交?
从上面看,rebase 之前的日志如下所示:
84e4015 - Me : Local Commit 3
0dbe86a - Me : Local Commit 2
d57ba2a - Me : Merge branch 'master' of remote repository
a86ea35 - Me : Local Commit 1 before reordering
2fc4fe7 - Remote User 2 : Remote Commit 2
b7a8656 - Remote User 1 : Remote Commit 1
8ce80fc - Me : Merge branch 'master' of remote repository
rebase 后的日志如下所示:
cf1ff7b - Me : Local Commit 3
cd14463 - Me : Local Commit 2
b9d44fb - Me : Local Commit 1 after reordering
9777c56 - Remote User 2 : Remote Commit 2
a2d7d8b - Remote User 1 : Remote Commit 1
8ce80fc - Me : Merge branch 'master' of remote repository
请注意,原来的 2 个提交 2fc4fe7 和 b7a8656 有新的 SHA; 9777c56 和 a2d7d8b。我相信这是问题的开始。
现在,在我执行另一个 git 后,拉取日志如下所示:
e8e1a85 - Me : Merge branch 'master' of remote repository
cf1ff7b - Me : Local Commit 3
cd14463 - Me : Local Commit 2
b9d44fb - Me : Local Commit 1 after reordering
9777c56 - Remote User 2 : Remote Commit 2
a2d7d8b - Remote User 1 : Remote Commit 1
2fc4fe7 - Remote User 2 : Remote Commit 2 // duplicate 2
b7a8656 - Remote User 1 : Remote Commit 1 // duplicate 1
8ce80fc - Me : Merge branch 'master' of remote repository
请注意,远程提交现在已复制,并且远程提交的原始 SHA 2fc4fe7 和 b7a8656 已返回。
在 Roger 的回复中,他说这看起来像是其他人推送到 git 的错误,他们正在重新设置已经推送的提交。但我认为在本地重新定位推送提交是我的错。
这是因为我重新定位了一个已经推送到远程的提交吗?如果是这样,我应该怎么做才能避免这种情况?我需要重新调整我的提交,以便我可以推送单个提交。我应该使用分支系统来做到这一点吗?如果是这样,我将如何使用分支来解决这个问题?
简短的回答是变基不会改变提交,1而是复制它们。 Git 通常会隐藏原件,但如果您的原件包含其他用户共享的那些,您(当然还有他们)仍然会看到这些原件。
作为一般规则,您应该只变基您自己的私有的、未发布的提交。由于没有人 else 根据定义拥有这些副本,因此您制作自己的副本然后(通过变基)隐藏您的原件这一事实不是问题:您现在可以看到您的副本而不是你的原件,其他人也看不到,如果需要,你可以继续变基。但是,一旦您发布(通过 push
或类似方式)提交,您就不能再更改它,因为其他人现在拥有您的原始副本,包括其 SHA-1 ID,并且他们仍然拥有稍后。
在这种情况下,您所做的是变基(即复制)他们的 提交以及您自己的提交。部分问题源于使用 git pull
,这意味着 "fetch then merge",而您想要的是 "fetch then rebase"。您可以单独执行以下步骤:
git fetch
git rebase
或使用git pull --rebase
:
git pull --rebase
它告诉 pull
脚本在执行提取后,它应该执行变基而不是合并。您还可以将 git 配置为自动执行此操作,而无需 --rebase
参数。2
现在的主要问题是您有一个您可能不想要的合并。如果是这样,您将需要 "undo" 合并(使用 git reset
;请参阅其他 Whosebug 帖子)。
1它不能:git 对象(包括提交)由其对象 ID 命名,它是其内容的加密校验和。提交由其父 ID、树的 ID、提交的作者和提交者(姓名、电子邮件和时间戳)以及提交消息组成。如果您更改其中任何一项,您将获得一个具有不同 ID 的新的、不同的提交。
2您甚至可以将其配置为使用 git pull --rebase=preserve
。但是,跨变基操作保留合并是一个单独的主题(我之前在 Whosebug 帖子中已经介绍过)。
我想将多个单个提交推送到 git 远程仓库。我按照杰夫在这里找到的答案这样做:
How can I pushing specific commit to a remote, and not the previous commits?
我想推送的提交不在最前面,所以我必须先使用 rebase 重新排序提交,我使用了这些指令来这样做:
http://gitready.com/advanced/2009/03/20/reorder-commits-with-rebase.html
基本上我已经完成了:
git clone
git commit
git commit
...
git pull
git rebase -i HEAD~3
git push origin <SHA>:master
我在执行此操作时遇到错误。所以我开始更深入地研究这个问题。我发现如果我在变基后进行第二次 git 拉取,我的日志中会出现重复提交,例如:
git clone
git commit
git commit
...
git pull
git log --pretty=format:"%h - %an : %s" // log before rebasing
git rebase -i HEAD~3
git pull
git log --pretty=format:"%h - %an : %s" // log after rebasing
git pull
git log --pretty=format:"%h - %an : %s" // log after rebasing after pulling
所以我发布了这个问题:
Roger 的回答让我想到了这个问题:为什么我在变基和拉动后看到重复提交?
从上面看,rebase 之前的日志如下所示:
84e4015 - Me : Local Commit 3
0dbe86a - Me : Local Commit 2
d57ba2a - Me : Merge branch 'master' of remote repository
a86ea35 - Me : Local Commit 1 before reordering
2fc4fe7 - Remote User 2 : Remote Commit 2
b7a8656 - Remote User 1 : Remote Commit 1
8ce80fc - Me : Merge branch 'master' of remote repository
rebase 后的日志如下所示:
cf1ff7b - Me : Local Commit 3
cd14463 - Me : Local Commit 2
b9d44fb - Me : Local Commit 1 after reordering
9777c56 - Remote User 2 : Remote Commit 2
a2d7d8b - Remote User 1 : Remote Commit 1
8ce80fc - Me : Merge branch 'master' of remote repository
请注意,原来的 2 个提交 2fc4fe7 和 b7a8656 有新的 SHA; 9777c56 和 a2d7d8b。我相信这是问题的开始。
现在,在我执行另一个 git 后,拉取日志如下所示:
e8e1a85 - Me : Merge branch 'master' of remote repository
cf1ff7b - Me : Local Commit 3
cd14463 - Me : Local Commit 2
b9d44fb - Me : Local Commit 1 after reordering
9777c56 - Remote User 2 : Remote Commit 2
a2d7d8b - Remote User 1 : Remote Commit 1
2fc4fe7 - Remote User 2 : Remote Commit 2 // duplicate 2
b7a8656 - Remote User 1 : Remote Commit 1 // duplicate 1
8ce80fc - Me : Merge branch 'master' of remote repository
请注意,远程提交现在已复制,并且远程提交的原始 SHA 2fc4fe7 和 b7a8656 已返回。
在 Roger 的回复中,他说这看起来像是其他人推送到 git 的错误,他们正在重新设置已经推送的提交。但我认为在本地重新定位推送提交是我的错。
这是因为我重新定位了一个已经推送到远程的提交吗?如果是这样,我应该怎么做才能避免这种情况?我需要重新调整我的提交,以便我可以推送单个提交。我应该使用分支系统来做到这一点吗?如果是这样,我将如何使用分支来解决这个问题?
简短的回答是变基不会改变提交,1而是复制它们。 Git 通常会隐藏原件,但如果您的原件包含其他用户共享的那些,您(当然还有他们)仍然会看到这些原件。
作为一般规则,您应该只变基您自己的私有的、未发布的提交。由于没有人 else 根据定义拥有这些副本,因此您制作自己的副本然后(通过变基)隐藏您的原件这一事实不是问题:您现在可以看到您的副本而不是你的原件,其他人也看不到,如果需要,你可以继续变基。但是,一旦您发布(通过 push
或类似方式)提交,您就不能再更改它,因为其他人现在拥有您的原始副本,包括其 SHA-1 ID,并且他们仍然拥有稍后。
在这种情况下,您所做的是变基(即复制)他们的 提交以及您自己的提交。部分问题源于使用 git pull
,这意味着 "fetch then merge",而您想要的是 "fetch then rebase"。您可以单独执行以下步骤:
git fetch
git rebase
或使用git pull --rebase
:
git pull --rebase
它告诉 pull
脚本在执行提取后,它应该执行变基而不是合并。您还可以将 git 配置为自动执行此操作,而无需 --rebase
参数。2
现在的主要问题是您有一个您可能不想要的合并。如果是这样,您将需要 "undo" 合并(使用 git reset
;请参阅其他 Whosebug 帖子)。
1它不能:git 对象(包括提交)由其对象 ID 命名,它是其内容的加密校验和。提交由其父 ID、树的 ID、提交的作者和提交者(姓名、电子邮件和时间戳)以及提交消息组成。如果您更改其中任何一项,您将获得一个具有不同 ID 的新的、不同的提交。
2您甚至可以将其配置为使用 git pull --rebase=preserve
。但是,跨变基操作保留合并是一个单独的主题(我之前在 Whosebug 帖子中已经介绍过)。